<%
'######################################################################
'## ab.c.asp
'## -------------------------------------------------------------------
'## Feature     :   AspBox Core Fucntion [AspBox Common Class]
'## Version     :   v1.0.2.0
'## Author      :   Lajox(lajox@19www.com)
'## Update Date :   2014/12/10 23:22
'## Description :   AspBox Common Function
'######################################################################

Class Cls_AB_C

	Private o_fso, o_regex
	Private o_rwt, i_rule
	Private s_charset, s_dict, s_url, s_rwtS, s_rwtU, s_rq

	Private Sub Class_Initialize()
		s_dict 	= AB.DictName
		s_charset = AB.CharSet
		Set o_regex = New Regexp
		Set o_rwt = Server.CreateObject(s_dict)
		o_regex.Global = True
		o_regex.IgnoreCase = True
		i_rule = 1
		s_rq = Request.QueryString()
	End Sub

	Private Sub Class_Terminate()
		Set o_regex = Nothing
		Set o_rwt	= Nothing
		If isObject(o_fso) Then Set o_fso = Nothing
	End Sub

	'==输出操作==

	Public Sub Print(ByVal s) '引用c#输出
		Response.Write s
	End Sub
	Public Sub Echo(ByVal s): Response.Write s: End Sub '引用PHP输出
	Public Sub W(ByVal s): Response.Write s: End Sub

	Public Sub Put(ByVal s) '输出终止
		Response.Write s
		AB.Exit()
		Set AB = Nothing
		Response.End()
	End Sub
	Public Sub WE(ByVal s): Put s: End Sub

	Public Sub Die(ByVal s) '引用PHP抛出异常
		Response.Clear
		Response.Write s
		Response.End()
	End Sub

	Public Sub PrintLn(ByVal s)
		Response.Write(s & VbCrLf)
	End Sub
	Public Sub Wn(ByVal s): Response.Write(s & VbCrLf): End Sub

	Public Sub PrintCn(ByVal s)
		Response.Write("<br /"&">" & s & VbCrLf)
	End Sub
	Public Sub WR(ByVal s): Response.Write("<br /"&">" & s & VbCrLf): End Sub

	Public Sub PrintFn(ByVal s)
		Response.Write s
		Response.Flush()
	End Sub
	Public Sub WF(ByVal s): Response.Write s: Response.Flush(): End Sub

	Public Sub Clear
		Response.Clear()
	End Sub
	Public Sub CC: Response.Clear(): End Sub

	Public Sub Flush
		Response.Flush()
	End Sub

	Public Sub PrintBin(ByVal s) '输出二进制流
		Response.BinaryWrite s
	End Sub
	Public Sub WBin(ByVal s): Response.BinaryWrite s: End Sub
	Public Sub WB(ByVal s): Response.BinaryWrite s: End Sub

	Public Sub WNH(ByVal s)
		PrintCn HtmlEncode(s)
	End Sub

	Public Sub WS(ByVal s)
		AB.Use "Json"
		Response.Write AB.Json.toJson(s)
	End Sub

	Public Sub WSN(ByVal s)
		AB.Use "Json"
		Response.Write("<br /"&">" & AB.Json.toJson(s) & VbCrLf)
	End Sub

	Public Sub [End]
		AB.Exit()
		Response.End()
	End Sub

	'----------------------------------------------------------------------------------------------

	'实现类似ceil函数。小数点自动升为整数+1，ceil(a)是求不小于a的最小整数
	Public Function Ceil(Byval p)
		Dim t
		't = Abs(Int(-p))
		t = Int(p) : If p-t>0 Then t = t + 1
		Ceil = t
	End Function

	'实现类似floor函数。返回不大于 x 的下一个整数，将 x 的小数部分舍去取整。
	Public Function Floor(Byval p)
		Floor = Int(p)
	End Function

	'四舍五入(精确到n位小数) e.g. AB.C.Round(-5.657, 2) 精确到2位小数值为-5.66
	Public Function Round(Byval p, Byval n)
		Round = CDbl( FormatNumber(p,n,-1,0,0) )
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Dim(s)
	'@ 别  名:  AB.C.Var(s) 或 AB.C.Reg(s)
	'@ 返  回:  无返回值
	'@ 作  用:  定义(注册)ASP全局变量, 此方法可以防止变量重定义问题
	'==DESC=====================================================================================
	'@ 参数 s : String (字符串) 变量名字符串
	'==DEMO=====================================================================================
	'@ AB.C.Dim("rs") '定义全局变量：rs ;相当于语句：Dim rs
	'@ AB.C.Dim "conn" '定义全局变量：conn ;相当于语句：Dim conn
	'@ AB.C.Dim "a, b, c" '定义多个变量之间用逗号(,)隔开：a, b, c ;相当于语句：Dim a, b, c
	'@ *****************************************************************************************

	Public Function [Dim](Byval s)
		On Error Resume Next
		ExecuteGlobal "Dim " & s
		On Error Goto 0
	End Function

	Public Function Var(Byval s)
		[Dim] s
	End Function

	Public Function Reg(Byval s)
		[Dim] s
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IsDim(s)
	'@ 返  回:  布尔值
	'@ 作  用:  检测变量是否已被定义
	'==DESC=====================================================================================
	'@ 参数 s : String (字符串) 变量名字符串
	'==DEMO=====================================================================================
	'@ Dim a : a = "var:a"
	'@ AB.C.PrintCn "变量a 是否已定义："& AB.C.IsDim("a") '输出：True
	'@ AB.C.PrintCn "变量b 是否已定义："& AB.C.IsDim("b") '输出：False
	'@ *****************************************************************************************

	Public Function IsDim(ByVal s)
		On Error Resume Next
		Dim tmp, p : p = Eval("VarType("& s &")")
		Select Case p
			Case vbEmpty,0,Empty : tmp = False '未初始化
			Case Else : tmp = True
		End Select
		IsDim = tmp
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Exec Str
	'@ 返  回:  无返回值
	'@ 作  用:  执行ASP脚本语句(即Execute的缩写)
	'==DESC=====================================================================================
	'@ 参数 Str : 待执行的ASP脚本语句
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function Exec(Byval s) '执行ASP脚本
		Dim tStr : tStr = s
		IF IsNul(tStr) Then : tStr = "" : Exit Function : End IF
		On Error Resume Next
		Execute tStr
		On Error Goto 0
	End Function

	'@ ********************************************************************************
	'@ AB.C.New(objName) [智能]创建对象(返回对象),当创建失败则返回Nothing
	'@ 功能: 创建对象(智能创建对象)
	'@ author: Lajox; version: 1.1.0 (2012-01-31);
	'==DESC============================================================================
	'@ [arg] objName : 对象/对象名/类名
	'==DEMO============================================================================
	'@ Dim o1, o2, o3, o4, o5, o6, o7
	'@ Set o1 = AB.C.New(AB) '等同于 Set o1 = AB
	'@ Set o2 = AB.C.New("AB") '等同于 Set o2 = AB
	'@ Set o3 = AB.C.New("Cls_AB") '等同于 Set o3 = New Cls_AB
	'@ Set o4 = AB.C.New("Scripting.Dictionary") '等同于 Set o4 = Server.CreateObject("Scripting.Dictionary")
	'@ Set o5 = AB.C.New("Cls_AB_E") '等同于 Set o5 = New Cls_AB_E
	'@ Set o6 = AB.C.New("AB.E") '等同于 Set o6 = AB.E
	'@ Set o7 = AB.C.New("abcd1445") '因为abcd1445既不是对象又不是类名，所有对象创建失败，返回值：Nothing
	'@ AB.Trace Array(TypeName(o1), TypeName(o2), TypeName(o3), TypeName(o4), TypeName(o5), TypeName(o6), TypeName(o7))
	'@ ********************************************************************************

	Public Function [New](ByVal objName)
		On Error Resume Next
		If IsObject(objName) Then
			Set [New] = objName
		Else
			If VarType(objName) = 8 Then 'vbString
				Execute "If IsObject(" & objName & ") Then : Set [New] = " & objName & " : Else : " &_
				"If IsInstall(""" & objName & """) Then : Set [New] = Server.CreateObject(""" & objName & """) : Else : Set [New] = New " & objName & " : End If" &_
				" : End If"
				Execute "If Err<>0 Then : Err.Clear : " &_
				"If IsInstall(""" & objName & """) Then : Set [New] = Server.CreateObject(""" & objName & """) : Else : Set [New] = New " & objName & " : End If" &_
				" : End If"
				Execute "If Err<>0 Then : Err.Clear : Set [New] = New " & objName & " : End If"
				Execute "If Err<>0 Then : Set [New] = Nothing : Err.Clear : End If"
			Else
				Set [New] = Nothing
			End If
		End If
		If Err Then : Set [New] = Nothing : Err.Clear : End If
		On Error Goto 0
	End Function

	'@ ********************************************************************************
	'@ AB.C.Free(o) 销毁多个对象,释放内存
	'@ 功能: 销毁对象(可以多个),释放内存
	'@ author: Lajox; version: 1.1.0 (2012-12-13);
	'==DESC============================================================================
	'@ 参数 o 说明:
	'@ 1.当参数[o]做为对象(Object)：(注：此用法某些情况下不能完全释放，建议用“对象名”字符串作为参数)
	'@   销毁单一对象，如 AB.C.Free(obj)
	'@ 2.当参数[o]做为字符串(String)：(建议用此方法)
	'@   销毁单一对象，用引号引进对象名，如 AB.C.Free("obj")
	'@   销毁多个对象，在每个对象名之间用英文逗号(,)隔开，如 AB.C.Free("objA,objB")
	'@ 3.当参数[o]做为数组(Array)：
	'@   销毁单一对象，AB.C.Free(Array("obj"))
	'@   销毁多个对象，AB.C.Free(Array("objA", "objB", "objC")) 或 AB.C.Free(Array("objA, objB, objC"))
	'==DEMO============================================================================
	'@ 调用示例:
	'@ dim o_a, o_b, o_c
	'@ set o_a = AB.Dict
	'@ set o_b = new Cls_AB_C
	'@ set o_c = new Cls_AB_Error
	'@ ab.c.print "======对象释放之前：======"
	'@ ab.trace o_a : ab.trace o_b : ab.trace o_c
	'@ '_对象释放操作:
	'@ 'ab.c.free o_a : ab.c.free o_b : ab.c.free o_c
	'@ ab.c.free "o_a, o_b, o_c"
	'@ 'ab.c.free Array("o_a", "o_b", "o_c")
	'@ 'ab.c.free Array("o_a, o_b, o_c")
	'@ '_操作结束
	'@ ab.c.print "======对象释放之后：======"
	'@ ab.trace o_a : ab.trace o_b : ab.trace o_c
	'@ ********************************************************************************

	Public Function Free(ByRef o)
		On Error Resume Next
		IF IsNull(o) Or IsEmpty(o) Then Exit Function
		Dim i,j,arr,str
		IF VarType(o)=8 Then '字符串
			AB.Free(o)
		ElseIF IsObject(o) Then
			str = LCase(TypeName(o))
			If str="connection" Then : If o.State=1 Then o.Close() : End If
			If str="recordset" Then : If o.State=1 Then o.Close() : End If
			If str="dictionary" Then '字典对象
				If Has(o) Then
					For Each j In o : Set o(j) = Nothing : Next : o.RemoveAll
				End If
			End If
			Execute("Set o = Nothing")
		ElseIf IsArray(o) Then
			If UBound(o)=-1 Then Exit Function
			For Each i In o
				If VarType(i)=8 Or IsObject(i) Then
					Me.Free(i)
				End If
			Next
		End IF
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 函数名:  AB.C.NewRs()
	'@ 返  回:  Rs记录集对象
	'@ 作  用:  创建新的Rs记录集对象
	'==DESC=====================================================================================
	'@ 参数 : 无
	'==DEMO=====================================================================================
	'@ Dim oRs : Set oRs = AB.C.NewRs()
	'@ *****************************************************************************************

	Public Function NewRs()
		Set NewRs = Server.CreateObject("Adodb.Recordset")
	End Function

	'@ ********************************************************************************
	'@ AB.C.Close(obj) 关闭对象并销毁对象,释放资源
	'@ 功能: 由Set语句创建打开的指定对象注销并释放资源
	'@ author: Lajox; version: 1.0.1 (2012-06-09);
	'==Args============================================================================
	'@ obj : 需要关闭的对象 # [Object]
	'==DEMO============================================================================
	'@ 无
	'@ ********************************************************************************

	Public Sub Close(ByRef o)
		On Error Resume Next
		If IsObject(o) Then 'Object
			o.Close() : Set o = Nothing
		ElseIF VarType(o) = 8 Then 'String
			Dim temp : temp = Eval("LCase(TypeName(o))")
			If temp = "connection" Then : Execute("If o.State = 1 Then o.Close()") : End If
			If temp = "recordset" Then : Execute("If o.State = 1 Then o.Close()") : End If
			Execute("Set "& o &" = Nothing")
		End If
		On Error Goto 0
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.C.Clone(o)
	'# @syntax: str2 = AB.C.Clone(str1) 或 Set obj2 = AB.C.Clone(obj1)
	'# @return: [Dictionary Object] (字典对象)
	'# @dowhat: 用于克隆(复制拷贝)一个字典对象,或数组,或其他数据..
	'--DESC------------------------------------------------------------------------------------
	'# @param o: [Any] (任意值: String/Array/Dictionary/..)
	'--DEMO------------------------------------------------------------------------------------
	'# Dim a1,a2,a3,a4
	'# Dim o1,o2,o3,o4
	'# a1 = "测试字符串" : o1 = AB.C.Clone(a1) '克隆字符串
	'# a2 = Array("a","b","c") : o2 = AB.C.Clone(a2) '克隆数组
	'# Set a3 = AB.Dict : Set o3 = AB.C.Clone(a3) '克隆字典对象
	'# Set a4 = AB.db.GRS("select 1 from table") : Set o4 = AB.C.Clone(a4) '克隆rs对象
	'# AB.Trace Array(a1,a2,a3,a4)
	'# AB.Trace Array(o1,o2,o3,o4)
	'------------------------------------------------------------------------------------------

	Public Function Clone(ByVal o)
		On Error Resume Next
		Dim tmp
		If IsObject(o) Then
			If TypeName(o)="Dictionary" Then
				Set tmp = CloneDict(o)
			ElseIf TypeName(o)="Recordset" Then
				Set tmp = o.Clone
			ElseIf TypeName(o)="Connection" Then
				' Set tmp = Server.CreateObject("ADODB.Connection")
				' If o.State = 1 Then
					' tmp.Open o.ConnectionString
					' If Err Then tmp.Close
				' End If
				Set tmp = o
			Else
				Set tmp = o
			End If
		ElseIf IsArray(o) Then
			AB.Use "A"
			tmp = AB.A.Clone(o)
		Else
			tmp = o
		End If
		If IsObject(tmp) Then Set Clone = tmp Else Clone = tmp
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.CallFunc FuncName, Param
	'@ 别  名:  AB.C.Call FuncName, Param
	'@ 返  回:  可以有返回值
	'@ 作  用:  调用(执行)自定义函数。
	'==DESC=====================================================================================
	'@ 参数 FuncName : 函数名 [String]
	'@ 参数 Param : 执行函数的参数 [Array | String | Null | ..] 数组时表示为参数数组
	'==DEMO=====================================================================================
	'@ Function foo(a,b,c) : foo = a + b - c : End Function
	'@ Function Jack() : Jack = Array("a",2) : End Function
	'@ AB.C.PrintCn foo(1,3,2) '输出：2
	'@ AB.C.PrintCn AB.C.Call("foo", Array(1,3,2)) '输出：2
	'@ AB.Trace Jack() '返回值：Array("a",2)
	'@ AB.Trace AB.C.Call("Jack", Null) '返回值：Array("a",2)
	'@ *****************************************************************************************

	Public Function CallFunc(ByVal s, ByVal p)
		On Error Resume Next
		If Err Then Err.Clear
		Dim sFunc, param : sFunc = s : param = p
		Dim i, temp, Result
		If IsArray(param) Then
			For i = 0 To UBound(param)
				If i = 0 Then
					temp = "param("& i &")"
				Else
					temp = temp & ", param("& i &")"
				End If
			Next
			Execute("Result = "& sFunc &"("& temp &")")
			Execute("If Err Then : Err.Clear: Result = "& sFunc &"(param) : End If")
		Else
			Execute("Result = "& sFunc &"(param)")
			If Err Then : Execute("Result = "& sFunc &"()") : End If
		End If
		CallFunc = Result
		On Error Goto 0
	End Function
	Public Function [Call](ByVal s, ByVal p) : [Call] = CallFunc(s, p) : End Function

	'---------------------------------------------------------------------
	'# AB.C.Count(sSource,sFind)
	'# @return: integer
	'# @dowhat: 搜索(字符串)或(数组)或(字典对象)等里含有多少个某子项值
	'# @author: Lajox; version: 1.0.0 (2012-04-21 17:24)
	'--DESC---------------------------------------------------------------
	'# @param sSource [String/Array/Dictionary/..] : 原字符串/数组/字典对象等等
	'# @param sFind   [string] : 要搜索的子项值/键名
	'--DEMO---------------------------------------------------------------
	'# AB.C.PrintCn AB.C.Count("abcddabcd","d") '输出：3
	'# AB.C.PrintCn AB.C.Count(Array("a","b","c","b"),"b") '输出：2
	'# AB.C.PrintCn AB.C.Count(AB.Dict,"fso") '输出：1 (检索字典对象是否含有键名“fso”)
	'#--------------------------------------------------------------------

	Function Count(Byval sSource, Byval sFind)
		Dim iCount : iCount = 0
		Dim i, j, o, k
		If isObject(sSource) Then Set o = sSource Else o = sSource
		If isObject(sFind) Then Set k = sFind Else k = sFind
		Select Case VarType(o)
			Case vbEmpty, vbNull
				iCount = 0
			Case vbBoolean, vbInteger, vbLong, vbSingle, vbDouble, vbCurrency, vbDate, vbByte
				If k = o Then iCount = 1 Else iCount = 0
			Case vbObject
				Select Case TypeName(o)
					Case "Nothing","Empty"
						iCount = 0
					Case "Recordset"
						If o.State = 0 Then
							iCount = 0
						Else
							If IsNul(o) Then
								iCount = 0
							Else
								For j = 0 To o.Fields.Count-1
									If k = o.Fields(j).value Then iCount = iCount+1
								Next
								'If o.Eof Then iCount = 0
							End If
						End If
					Case "Dictionary"
						If o.Count = 0 Then
							iCount = 0
						Else
							If o.Exists(k) Then
								For Each i In o
									'If k = o(i) Then iCount = iCount+1
									If k = i Then iCount = iCount+1
								Next
							Else
								iCount = 0
							End If
						End If
					Case "Cls_AB_List"
						If o.Size = 0 Then
							iCount = 0
						Else
							For i = 0 To o.End
								If k = o(i) Then iCount = iCount+1
							Next
						End If
					Case Else
						If TypeName(o) = TypeName(k) Then
							iCount = 1
						Else
							iCount = 0
						End If
				End Select
			Case vbString
				If Len(o)>0 and Len(k)>0 Then iCount=(Len(o)-Len(Replace(o,k,"")))/Len(k)
				If k = o Then iCount = 1
			Case vbArray,8194,8204,8209
				AB.Use "A" : iCount = AB.A.Count(o, k)
			Case Else
				iCount = 0
		End Select
		Count = iCount
	End Function

	'---------------------------------------------------------------------
	'# AB.C.vOr(s)
	'# @return: Boolean (布尔值)
	'# @dowhat: 简写多个Or条件
	'#  单条件：语法：If 条件 Then 可简写为：If AB.C.vOr(条件) Then
	'#  多条件：语法：If 条件1 Or 条件2 Or 条件3 Then 可简写为：If AB.C.vOr(Array(条件1,条件2,条件3)) Then
	'--DESC---------------------------------------------------------------
	'# @param s [Boolean/Array] : 条件判断(Boolean) 或 一个包含多个条件判断的数组(Array)
	'--DEMO---------------------------------------------------------------
	'# Dim var : var = 2.3
	'# 'If var=1 Or var="c" Or var<2.5 Then AB.C.Print var
	'# 'If AB.C.vOr(var=1 Or var="c" Or var<2.5) Then AB.C.Print var
	'# 'If AB.C.vOr(Array(var=1 Or var="c" Or var<2.5)) Then AB.C.Print var
	'# If AB.C.vOr(Array(var=1, var="c", var<2.5)) Then AB.C.Print var
	'#--------------------------------------------------------------------

	Function vOr(Byval s)
		On Error Resume Next
		Dim bool : bool = False
		If Err Then Err.Clear
		If IsArray(s) Then
			Dim i
			For Each i In s
				bool = bool Or vOr(i)
			Next
		Else
			bool = CBool(s)
			If Err.Number<>0 Then bool = s
		End If
		vOr = bool
		On Error Goto 0
	End Function

	'---------------------------------------------------------------------
	'# AB.C.vAnd(s)
	'# @return: Boolean (布尔值)
	'# @dowhat: 简写多个Or条件
	'#  单条件：语法：If 条件 Then 可简写为：If AB.C.vAnd(条件) Then
	'#  多条件：语法：If 条件1 and 条件2 and 条件3 Then 可简写为：If AB.C.vAnd(Array(条件1,条件2,条件3)) Then
	'--DESC---------------------------------------------------------------
	'# @param s [Boolean/Array] : 条件判断(Boolean) 或 一个包含多个条件判断的数组(Array)
	'--DEMO---------------------------------------------------------------
	'# Dim var : var = 1.2
	'# 'If var>1 And var<2.5 Then AB.C.Print var
	'# 'If AB.C.vAnd(var>1 And var<2.5) Then AB.C.Print var
	'# If AB.C.vAnd(Array(var>1, var<2.5)) Then AB.C.Print var
	'#--------------------------------------------------------------------

	Function vAnd(Byval s)
		On Error Resume Next
		Dim bool : bool = True
		If Err Then Err.Clear
		If IsArray(s) Then
			Dim i
			For Each i In s
				bool = bool And vAnd(i)
			Next
		Else
			bool = CBool(s)
			If Err.Number<>0 Then bool = s
		End If
		vAnd = bool
		On Error Goto 0
	End Function

	'@ ********************************************************************************
	'@ AB.C.IsNum(s) 判断是否为整数形式(纯数字规则)
	'@ 返  回:  Boolean (布尔值)
	'@ 功  能:  判断某串字符是否为整数形式
	'==DESC============================================================================
	'@ [arg] s : 待检测的字符
	'@ -----------------------
	'@ 因用IsNumeric可能存在Bug,这个数值可不仅限于普通的数字：
	'@ # 科学计数法表达式，如“2e7”和“2d7”；
	'@ # 十六进制数，如“&H0A”；
	'@ # 八进制数，如“&6”；
	'@ # 当前区域下设置的货币金额表达式，如“￥12.44”；
	'@ # 加圆括号的数字，如“(34)”；
	'@ # 显式指定正负的数字，如“+2.1”和“-2.1”；
	'@ # 含有逗号的数字字符串，如“12,25”。
	'==DEMO============================================================================
	'@ AB.C.PrintCn AB.C.IsNum("2011") '=> True
	'@ AB.C.PrintCn AB.C.IsNum("100.01") '=> False
	'@ ********************************************************************************

	Function IsNum(Byval s)
		On Error Resume Next
		'Rem 用IsNumeric可能存在Bug,弃用!
		'IF Not IsNull(s) and Trim(s)<>"" Then:IsNum=IsNumeric(s):Else:IsNum=False:End IF
		Dim p : p = 0
		If IsArray(s) Then
			IsNum = False
			Exit Function
		End If
		If p = 0 Then '采用正则(效率高)
			IsNum = RegTest(s, "^\d+$")
		Else
			Dim I,oStr:oStr=CStr(s)
			Dim b:b=True
			If IsNull(s) Or Trim(s)="" Then
				b = False
			Else
				For I=1 To Len(oStr)
					If Mid(oStr,I,1)>"9" or Mid(oStr,I,1)<"0" Then:b=False:Exit For:End If
				Next
			End If
			IsNum = b
		End If
		IsNum = CBool(IsNum)
		On Error Goto 0
	End Function

	'@ ********************************************************************************
	'@ AB.C.IsInt(s) 判断字符类型是否整型
	'@ 返  回:  Boolean (布尔值)
	'@ 功  能:  判断变量类型是否整型
	'==DESC============================================================================
	'@ [arg] s : 待检测的变量
	'==DEMO============================================================================
	'@ AB.C.PrintCn AB.C.IsInt(2011) '=> True
	'@ AB.C.PrintCn AB.C.IsInt("2011") '=> False
	'@ ********************************************************************************

	Function IsInt(Byval s)
		Dim stype: stype = Lcase(TypeName(s))
		IF stype="integer" Or stype="long" Or stype="double" Or stype="single" Then
			IsInt = True
		Else
			IsInt = False
		End IF
	End Function

	'@ ********************************************************************************
	'@ AB.C.isStr(s) 判断是否为字符串
	'@ 返  回:  Boolean
	'@ 功  能:  判断变量类型是否为字符串
	'==DESC============================================================================
	'@ [arg] s : 待检测的变量
	'==DEMO============================================================================
	'@ AB.C.PrintCn AB.C.isStr("abcd") '=> True
	'@ ********************************************************************************

	Function isStr(Byval s)
		isStr = False
		If Not IsObject(s) And VarType(s) = vbString Then isStr = True
	End Function

	'@ ********************************************************************************
	'@ AB.C.IsBool(s) 判断是否为布尔值
	'@ 返  回:  Boolean
	'@ 功  能:  判断变量类型是否为布尔值
	'==DESC============================================================================
	'@ [arg] s : 待检测的变量
	'==DEMO============================================================================
	'@ AB.C.PrintCn AB.C.IsBool(False) '=> True
	'@ AB.C.PrintCn AB.C.IsBool(1 = 2) '=> True
	'@ AB.C.PrintCn AB.C.IsBool(0) '=> False
	'@ ********************************************************************************

	Function IsBool(Byval s)
		IsBool = False
		If VarType(s) = vbBoolean Then IsBool = True
	End Function

	'@ ********************************************************************************
	'@ AB.C.isRs(o) 判断是否为 Rs记录集对象
	'@ 返  回:  Boolean (布尔值)
	'@ 功  能:  判断变量类型是否为 Rs记录集对象
	'==DESC============================================================================
	'@ [arg] o : 待检测的变量
	'==DEMO============================================================================
	'@ Dim oRs : Set oRs = AB.C.NewRs()
	'@ AB.C.PrintCn AB.C.isRs(oRs) '=> True
	'@ ********************************************************************************

	Function isRs(Byval o)
		isRs = False
		If IsObject(o) and TypeName(o) = "Recordset" Then isRs = True
	End Function

	'@ ********************************************************************************
	'@ AB.C.IsConn(o) 判断是否为 Connection对象
	'@ 返  回:  Boolean (布尔值)
	'@ 功  能:  判断变量类型是否为 Connection对象
	'==DESC============================================================================
	'@ [arg] o : 待检测的变量
	'==DEMO============================================================================
	'@ AB.C.Print AB.C.isConn(AB.db.Conn)
	'@ ********************************************************************************

	Public Function IsConn(ByVal o)
		IsConn = False
		If Not IsObject(o) Then Exit Function
		If Lcase(TypeName(o)) = "connection" Then IsConn = True
	End Function

	'@ ********************************************************************************
	'@ AB.C.isDict(o) 判断是否为 Dictionary 字典对象
	'@ 返  回:  Boolean (布尔值)
	'@ 功  能:  判断字符类型是否为 Dictionary 字典对象
	'==DESC============================================================================
	'@ [arg] o : 待检测的字符或对象
	'==DEMO============================================================================
	'@ AB.C.PrintCn AB.C.isDict(AB.Dict) '=> True
	'@ ********************************************************************************

	Function isDict(Byval o)
		isDict = False
		If IsObject(o) and TypeName(o) = "Dictionary" Then isDict = True
	End Function

	'@ ********************************************************************************
	'@ AB.C.CheckDict(dict1, dict2)
	'@ 返  回:  Boolean (布尔值)
	'@ 功  能:  判断两个字典对象是否相等，若 dict1 或 dict2 不是字典对象则返回 False
	'@ 			注意：对于复杂的数据类型可能没办法判断那么准确. 此方法仅供参考。
	'==DESC============================================================================
	'@ [arg] dict1 : 待检测的字典对象1
	'@ [arg] dict2 : 待检测的字典对象2
	'==DEMO============================================================================
	'@ AB.C.PrintCn AB.C.CheckDict(AB.Dict, AB.DT) '=> True
	'@ Dim obj1, obj2
	'@ Set obj1 = AB.C.New(AB.dictName) '等同于 Server.CreateObject("Scripting.Dictionary")
	'@ Set obj2 = AB.C.New(AB.dictName)
	'@ obj1("a") = "x" : obj1("b") = "y"
	'@ obj2("o") = "k"
	'@ AB.C.PrintCn AB.C.CheckDict(obj1, obj2) '=> False
	'@ ********************************************************************************

	Function CheckDict(Byval dict1, Byval dict2)
		On Error Resume Next
		If isDict(dict1) and isDict(dict2) Then
			If dict1.Count <> dict1.Count Then : CheckDict = False : Exit Function : End If
			Dim i,j
			For Each i In dict1
				If IsObject(dict1(i)) And IsObject(dict2(i)) Then
					If TypeName(dict1(i)) <> TypeName(dict2(i)) Then CheckDict = False : Exit Function : End If
					Select Case TypeName(dict1(i))
						Case "Recordset"
							If dict1(i).State <> dict2(i).State Then CheckDict = False : Exit Function : End If
							Dim e1, e2 : e1 = False : e2 = False
							If dict1(i).Bof And dict2(i).Eof Then e1 = True
							If dict1(i).Bof And dict2(i).Eof Then e2 = True
							If e1 <> e2 Then CheckDict = False : Exit Function : End If
							If dict1(i).Fields.Count <> dict2(i).Fields.Count Then CheckDict = False : Exit Function : End If
							dict1(i).MoveFirst : dict2(i).MoveFirst
							While Not dict1(i).Eof
								For j = 0 To dict1(i).Fields.Count-1
									If dict1(i).Fields(j).Name <> dict2(i).Fields(j).Name Then CheckDict = False : Exit Function : End If
									If dict1(i).Fields(j).value <> dict2(i).Fields(j).value Then CheckDict = False : Exit Function : End If
								Next
								dict1(i).MoveNext : dict2(i).MoveNext
							Wend
						Case "Dictionary"
							If dict1(i).Count <> dict2(i).Count Then CheckDict = False : Exit Function : End If
							If Not CheckDict(dict1(i), dict2(i)) Then
								CheckDict = False : Exit Function
							End If
						Case "Nothing","Empty"
							'
						Case Else '对于这一步，复杂的数据不好处理！
							'
					End Select
				ElseIf Not IsObject(dict1(i)) And IsObject(dict2(i)) Then
					CheckDict = False : Exit Function
				ElseIf IsObject(dict1(i)) And Not IsObject(dict2(i)) Then
					CheckDict = False : Exit Function
				Else
					If dict1(i) <> dict2(i) Then
						CheckDict = False : Exit Function
					End If
				End If
			Next
			CheckDict = True
		Else
			CheckDict = False
		End If
		On Error Goto 0
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.C.Dict()
	'# @syntax: Set d = AB.C.Dict()
	'# @return: [Dictionary Object] (字典对象)
	'# @dowhat: 创建新字典
	'--DESC------------------------------------------------------------------------------------
	'# @param d: [variant] (变量)
	'--DEMO------------------------------------------------------------------------------------
	'# dim d
	'# Set d = AB.C.Dict()
	'# d.add "a", "值a"
	'# d.add "b", "值b"
	'# AB.Trace d
	'------------------------------------------------------------------------------------------

	Public Function Dict() '创建新字典
		Dim d : Set d = Server.CreateObject(s_dict) : d.CompareMode = 1
		Set Dict = d
		Set d = Nothing
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.C.SetDict()
	'# @syntax: AB.C.SetDict dict, key, value
	'# @return: [Dictionary Object] (字典对象)
	'# @dowhat: 字典对象设置项值
	'--DESC------------------------------------------------------------------------------------
	'# @param dict: [Dictionary Object] (字典对象)
	'# @param key: [String] (字符串)
	'# @param value: [Any] (任意值)
	'--DEMO------------------------------------------------------------------------------------
	'# dim dict
	'# Set dict = AB.C.Dict()
	'# dict("a") = "值a"
	'# dict("b") = "值b"
	'# AB.C.SetDict dict, "a", "变值a"
	'# AB.C.SetDict dict, "c", "值c"
	'# AB.Trace dict
	'------------------------------------------------------------------------------------------

	Public Sub SetDict(ByRef o, ByVal s, ByVal v)
		If isDict(o) Then
			If o.Exists(s) Then
				If IsObject(v) Then Set o(s) = v Else o(s) = v
			Else
				o.Add s, v
			End If
		End If
	End Sub

	'------------------------------------------------------------------------------------------
	'# AB.C.CloneDict(o)
	'# @syntax: Set dict2 = AB.C.CloneDict(dict1)
	'# @return: [Dictionary Object] (字典对象)
	'# @dowhat: 克隆新字典
	'--DESC------------------------------------------------------------------------------------
	'# @param dict1: [Any] (任意值)
	'# @param dict2: [Dictionary Object] (字典对象)
	'--DEMO------------------------------------------------------------------------------------
	'# dim dict1 : Set dict1 = AB.C.Dict()
	'# dict1("a") = "值a"
	'# dict1("b") = "值b"
	'# dim dict2 : Set dict2 = AB.C.CloneDict(dict1)
	'# AB.Trace dict2
	'------------------------------------------------------------------------------------------

	Public Function CloneDict(ByVal o)
		On Error Resume Next
		Dim item, d
		Set d = Server.CreateObject(s_dict) : d.CompareMode = 1
		If isDict(o) Then
			For Each item In o
				If d.Exists(item) Then
					If IsObject(o(item)) Then Set d(item) = o(item) Else d(item) = o(item)
				Else
					d.Add item, o(item)
				End If
			Next
		End If
		Set CloneDict = d
		Set d = Nothing
		On Error Goto 0
	End Function

	'------------------------------------------------------------------------------------------
	'# AB.C.ClearDict(o)
	'# @syntax: Set dict = AB.C.ClearDict(dict) 或 AB.C.SetDict dict
	'# @return: [Dictionary Object] (字典对象)
	'# @dowhat: 清空字典(所有项)
	'--DESC------------------------------------------------------------------------------------
	'# @param dict: [Dictionary Object] (字典对象)
	'--DEMO------------------------------------------------------------------------------------
	'# dim dict
	'# Set dict = AB.C.Dict()
	'# dict("a") = "值a"
	'# dict("b") = "值b"
	'# 'Set dict = AB.C.ClearDict(dict)
	'# AB.C.ClearDict dict
	'# AB.Trace dict
	'------------------------------------------------------------------------------------------

	Public Function ClearDict(ByRef o)
		If isDict(o) Then
			o.RemoveAll()
			Set ClearDict = o
		End If
	End Function

	'@ ********************************************************************************
	'@ AB.C.isInstr() 检查是否含有某字符串
	'@ 功能: 从特定的某些关键字中检查是否含有某关键字
	'@ author: Lajox; version: 1.0.0 (2011-08-22);
	'==DESC============================================================================
	'@ 参数说明:
	'@ t: 特定的某些关键字,用(,)隔开
	'@ s: 某关键字
	'==DEMO============================================================================
	'@ 调用示例:
	'@ AB.C.isInstr("hello,world,perfect", "world")
	'@ AB.C.isInstr("'ab','cd','efg'", "'cd'")
	'@ ********************************************************************************

	Public Function isInstr(Byval t, Byval s)
		Dim rt : rt = False
		Dim ta : ta = Replace(t & "", "|", ",")
		Dim I
		For I=0 To Ubound(Split(ta,","))
			IF Trim(s) = Split(ta,",")(I) Then:rt = True:Exit For:End IF
		Next
		isInstr = rt
	End Function

	'@ ********************************************************************************
	'@ AB.C.strRepeat(s, n)
	'@ 功能: 把字符串重复指定的次数
	'==DESC============================================================================
	'@ 参数说明:
	'@ s: 规定要重复的字符串
	'@ n: 规定字符串将被重复的次数。必须大于等于 0
	'==DEMO============================================================================
	'@ AB.C.Print AB.C.StrRepeat(".",13)
	'@ ********************************************************************************

	Public Function StrRepeat(Byval s, Byval n)
		Dim str : str = ""
		If IsNum(n) Then n = CLng(n)
		For i=1 To n
			str = str & s
		Next
		StrRepeat = str
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IIF condition, ifTrue, ifFalse
	'@ 返  回:  Anything (任意值)
	'@ 			如果condition参数表达式为真则返回ifTrue参数的值，为假则返回ifFalse参数的值
	'@ 作  用:  调用此方法时，将首先判断第1个参数中的表达式是否为真，
	'@ 			如果为真则返回第2个参数的表达式中的值，
	'@ 			如果为假则返回第3个参数的表达式中的值。
	'@ 			是If...Then...Else...End If的一种简写版本。类似于JavaScript中的 a ? b : c 表达式
	'==DESC=====================================================================================
	'@ condition : Expression (表达式)
	'@  一个或多个下面两种类型的表达式：
	'@ 	1、数值或字符串表达式，其运算结果是 True 或 False。
	'@ 	   如果 condition 是 Null，则 condition 被视为 False。
	'@ 	2、形如 TypeOf objectname Is objecttype 的表达式。
	'@ 	   objectname 是任何对象的引用，而 objecttype 则是任何有效的对象类型。
	'@ 	   如果 objectname 是 objecttype 所指定的一种对象类型，则表达式为 True；否则为 False。
	'@ ifTrue : Anything (任意值) 如果 condition 为 True 时要返回的值
	'@ ifFalse : Anything (任意值) 如果 condition 为 False 时要返回的值
	'==DEMO=====================================================================================
	'@ Result = AB.C.IIF(Instr("type","p")>0, "blue", "red")
	'@  如果Instr("type","p")的值大于0,则Result的值就为"blue"，反之则为"red"。
	'@ *****************************************************************************************

	Public Function IIF(ByVal Cn, ByVal T, ByVal F)
		If Cn Then
			If IsObject(T) Then
				Set IIF = T
			Else
				IIF = T
			End If
		Else
			If IsObject(F) Then
				Set IIF = F
			Else
				IIF = F
			End If
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IsNul var
	'@ 返  回:  var 参数为空则返回True，否则返回False
	'@ 作  用:  调用此方法将检测参数中的变量，并返回一个布尔值：，
	'@ 			如果object为Null值或空值(Empty)，返回真(True)；
	'@ 			如果object为字符串但是没有包含任何内容，返回真(True)；
	'@ 			如果object为对象且此对象目前类型为Nothing或Empty，返回真(True)；
	'@ 			如果object为数组且数组内没有包含任何元素，返回真(True)；
	'@ 			其它情况将返回假(False)。
	'==DESC=====================================================================================
	'@ 参数 var : Array (数组) 或 Object (ASP对象) 或 String (字符串) 待检测的变量
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function isNul(ByVal s)
		On Error Resume Next:IF Err.Number<>0 Then Err.Clear
		isNul = False
		Select Case VarType(s)
			Case vbEmpty, vbNull
				isNul = True : Exit Function
			Case vbString
				If s="" Then isNul = True : Exit Function
			Case vbObject
				Select Case TypeName(s)
					Case "Nothing","Empty"
						isNul = True : Exit Function
					Case "Recordset"
						If s.State = 0 Then isNul = True : Exit Function
						If s.Bof And s.Eof Then isNul = True : Exit Function
					Case "Dictionary"
						If s.Count = 0 Then isNul = True : Exit Function
				End Select
			Case vbArray,8194,8204,8209
				If Ubound(s)=-1 Then isNul = True : Exit Function
		End Select
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IsNone var
	'@ 返  回:  var 参数为空或只含空格符则返回True，否则返回False
	'@ 作  用:  调用此方法将检测参数中的变量，并返回一个布尔值：，
	'@ 			如果var为Null值或空值(Empty)，返回真(True)；
	'@ 			如果var为字符串但是没有包含任何内容或只有空格符，返回真(True)；
	'@ 			如果var为对象且此对象目前类型为Nothing或Empty，返回真(True)；
	'@ 			如果var为数组且数组内没有包含任何元素，返回真(True)；
	'@ 			如果var为数组且数组只有一个元素且该元素:没有包含任何内容或只有空格符，返回真(True)；
	'@ 			其它情况将返回假(False)。
	'==DESC=====================================================================================
	'@ 参数 var : Array (数组) 或 Object (ASP对象) 或 String (字符串) 待检测的变量
	'==DEMO=====================================================================================
	'@ AB.C.PrintCn AB.C.IsNone(" ") '返回 True
	'@ AB.C.PrintCn AB.C.IsNone(Null) '返回 True
	'@ AB.C.PrintCn AB.C.IsNone(array(" ")) '返回 True
	'@ AB.C.PrintCn AB.C.IsNone(array("", "")) '返回 False
	'@ *****************************************************************************************

	Public Function IsNone(ByVal s)
		On Error Resume Next:IF Err.Number<>0 Then Err.Clear
		IsNone = False
		Select Case VarType(s)
			Case vbEmpty, vbNull
				IsNone = True : Exit Function
			Case vbString
				If Trim(s)="" Then IsNone = True : Exit Function
			Case vbObject
				Select Case TypeName(s)
					Case "Nothing","Empty"
						IsNone = True : Exit Function
					Case "Recordset"
						If s.State = 0 Then IsNone = True : Exit Function
						If s.Bof And s.Eof Then IsNone = True : Exit Function
					Case "Dictionary"
						If s.Count = 0 Then IsNone = True : Exit Function
				End Select
			Case vbArray,8194,8204,8209
				If Ubound(s)=-1 Then IsNone = True : Exit Function
				If Ubound(s)=0 Then
					If IsObject(s(0)) Or IsArray(s(0)) Then
						IsNone = False
					ElseIf VarType(s(0))=vbEmpty Or VarType(s(0))=vbNull Then
						IsNone = True
					ElseIf VarType(s(0))=vbString Then
						If Trim(s(0))="" Then IsNone = True : Exit Function
					End If
				End If
		End Select
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.NoneIs value, var
	'@ 返  回:  value 或 var
	'@ 作  用:  检测的变量var不包含任何内容(或只含空格符)时返回 value值, 否则返回原var值。
	'==DESC=====================================================================================
	'@ [arg] value : Anything (任意值) 取代值
	'@ [arg] var : Anything (任意值) 检测的变量
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.NoneIs("为空时的取代值", " ") '输出： 为空时的取代值
	'@ *****************************************************************************************

	Public Function NoneIs(ByVal p, ByVal s)
		Dim t : t = IsNone(s)
		If IsObject(IIF(t,p,s)) Then
			Set NoneIs = IIF(t,p,s)
		Else
			NoneIs = IIF(t,p,s)
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Has var
	'@ 返  回:  如果不为空则返回 True， 为空返回 False
	'@ 作  用:  判断变量是否不为空，支持字符串、数组、记录集、Dictionary等对象
	'@ 			此方法和AB.C.IsNul方法恰好相反，用以检测变量是否不为空，
	'@ 			变量可以是字符串、数组、记录集、Dictionary等对象
	'==DESC=====================================================================================
	'@ [arg] var : Array (数组) 或 Recordset (记录集对象) 或 String (字符串) # 待检测的变量
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function Has(ByVal s)
		On Error Resume Next:Err.Clear
		Has = Not isNul(s)
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IfThen condition, ifTrue
	'@ 返  回:  "" (空字符串) 或 Anything (任意值)
	'@ 作  用:  此方法为AB.C.IIF的省略版
	'@ 			仅用于返回condition条件为真时的返回值，如果条件为假时则返回空字符串
	'==DESC=====================================================================================
	'@ [arg] condition : Expression (表达式) 用以判断的表达式
	'@ [arg] ifTrue : Anything (任意值) 如果表达式成立的返回值
	'==DEMO=====================================================================================
	'@ AB.C.IfThen(72>=60,"及格") 等同于 AB.C.IIF(72>=60,"及格","")
	'@ *****************************************************************************************

	Public Function IfThen(ByVal Cn, ByVal T)
		If IsObject(IIF(Cn,T,"")) Then
			Set IfThen = IIF(Cn,T,"")
		Else
			IfThen = IIF(Cn,T,"")
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IfHas ResultA, ResultB
	'@ 返  回:  ResultA 或 ResultB
	'@ 作  用:  此方法为AB.C.IIF的省略版
	'@ 			当ResultA不为空时返回结果ResultA，当ResultA为空时返回结果ResultB
	'==DESC=====================================================================================
	'@ ResultA : 当ResultA不为空时返回结果ResultA
	'@ ResultB : 当ResultA为空时返回结果ResultB
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function IfHas(ByVal v1, ByVal v2)
		Dim t : t = Has(v1)
		If IsObject(IIF(t, v1, v2)) Then
			Set IfHas = IIF(t, v1, v2)
		Else
			IfHas = IIF(t, v1, v2)
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.isFile filePath
	'@ 返  回:  布尔值(True/False)
	'@ 作  用:  判断文件是否存在
	'==DESC=====================================================================================
	'@ filePath: 可以是完整路径，也可以是相对路径
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function isFile(ByVal p)
		isFile = False
		If TypeName(o_fso)<>"FileSystemObject" Then Set o_fso = Server.CreateObject(AB.fsoName)
		If Trim(p)<>"" and Mid(p,2,1)<>":" Then p = Server.MapPath(p)
		If o_fso.FileExists(p) Then isFile = True
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.isFolder folderPath
	'@ 返  回:  布尔值(True/False)
	'@ 作  用:  判断文件夹是否存在
	'==DESC=====================================================================================
	'@ folderPath: 可以是完整路径，也可以是相对路径
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function isFolder(ByVal p)
		isFolder = False
		If TypeName(o_fso)<>"FileSystemObject" Then Set o_fso = Server.CreateObject(AB.fsoName)
		If Mid(p,2,1)<>":" Then p = Server.MapPath(p)
		If o_fso.FolderExists(p) Then isFolder = True
	End Function

	'---------------------------------------------------------------------
	'# AB.C.Split(sText,sSplit)
	'# @return: Array (数组)
	'# @dowhat: 字符串分割为数组,此方法是原Split函数的补充
	'# 			当分割字符sSplit值为空时，返回以每个字符组成的数组
	'# @author: Lajox; version: 1.0.0 (2012-04-21)
	'--DESC---------------------------------------------------------------
	'# @param sText [string] : 原字符串
	'# @param sSplit [string] : 分割字符
	'--DEMO---------------------------------------------------------------
	'# AB.Trace AB.C.Split("a,b,c",",") '返回：Array("a","b","c")
	'# AB.Trace AB.C.Split("abcd","") '返回：Array("a","b","c","d")
	'#--------------------------------------------------------------------

	Public Function Split(Byval sText, Byval sSplit)
		On Error Resume Next
		AB.Use "H"
		Split = AB.H.Split(sText,sSplit)
		On Error Goto 0
	End Function

	'---------------------------------------------------------------------
	'# AB.C.RegSplit(sText, expSplit, p)
	'# @return: Array (数组)
	'# @dowhat: 按正则字符串进行分割 返回数组
	'--DESC---------------------------------------------------------------
	'# @param sText [string] : 原字符串
	'# @param expSplit [string] : 正则字串
	'# @param p [int] : 返回结果类型:
	'# 					当 p=0 时; 返回 不包含正则符在内的元素的 数组
	'# 					当 p=1 时; 返回 包含正则符在内的元素的 数组
	'--DEMO---------------------------------------------------------------
	'# AB.Trace AB.C.RegSplit("abc<>def=cgg==hi", "[\<>=]+", 0) '返回数组 Array("abc", "def", "cgg", "hi")
	'# AB.Trace AB.C.RegSplit("abc<>def=cgg==hi", "[\<>=]+", 1) '返回数组 Array("abc", "<>", "def", "=", "cgg", "==", "hi")
	'#--------------------------------------------------------------------

	Public Function RegSplit(ByVal sText, ByVal expSplit, ByVal p)
		On Error Resume Next
		Dim Match, str : str = sText
		Dim sp : sp = "#@ljx:split@#"
		If IsNull(p) Or Trim(p)="" Then p = 0
		If p = 1 Then
			Dim d : Set d = Server.CreateObject(s_dict) : d.CompareMode = 1
			Dim i : i = 0
			If IsDict(d) Then
				For Each Match in RegMatch(str,expSplit)
					d.add i, Match.value
					i = i + 1
				Next
				str = RegReplace(str, expSplit, sp)
				Dim b : b = Split(str, sp)
				Dim a, elem, j, k : j = 0 : k = 0 : a = Array()
				If IsArray(b) Then
					AB.Use "A"
					If AB.A.Len(b)=-1 Then
						'a = Array()
					ElseIf AB.A.Len(b)=0 Then
						a = AB.A.Push(a, b(0))
					Else
						AB.Use "A"
						For j=0 To UBound(b)
							If (j Mod 2) = 1 Then
								If d.Exists(k) Then
									a = AB.A.Push(a, d.Item(k))
									k = k + 1
								End If
								a = AB.A.Push(a, b(j))
							Else
								If j>0 Then
									If d.Exists(k) Then
										a = AB.A.Push(a, d.Item(k))
										k = k + 1
									End If
								End If
								a = AB.A.Push(a, b(j))
							End If
						Next
					End If
				End If
				Set d = Nothing
				RegSplit = a
			End If
		Else
			str = RegReplace(str, expSplit, sp)
			RegSplit = Split(str, sp)
		End If
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RP(Str, FindStr, RepStr)
	'@ 返  回:  [String]
	'@ 作  用:  通用替换函数(可替代常规的Replace函数)
	'  a. 如果 FindStr 和 RepStr 均为非数组，那么 将做普通替换, 等同于 Replace(Str,FindStr,RepStr)。
	'  b. 如果 FindStr 和 RepStr 为数组，那么 AB.C.RP() 将对 Str 做二者的映射替换。
	'  c. 如果 RepStr 数组的个数少于 FindStr 数组的个数，多余的替换将使用空字符串来进行替换。
	'  d. 如果 FindStr 是一个数组而 RepStr 是一个字符串，那么 FindStr 中每个元素的替换将始终使用这个字符串。
	'==DESC=====================================================================================
	'@ 参数: Str 字符串, FindStr 查找字符串, RepStr 要替换字符串
	'@ --系统自带的常规Replace(Str,FindStr,RepStr,1,-1,1)参数
	'@ --第④个参数: 指定从第几个字符开始搜索该字符串
	'@ --第⑤个参数: 1表示只有第一次出现时进行替换,
	'               -1表示指定每一个子串都要被替换
	'@ --第⑥个参数: 1指定字符串的比较不区分大小写
	'==DEMO=====================================================================================
	'@ AB.C.PrintCn AB.C.RP("abcd", "bc", "-") '=> "a-d"
	'@ AB.C.PrintCn AB.C.RP("abcd", array("b","c"), array("x","y")) '=> "axyd"
	'@ AB.C.PrintCn AB.C.RP("abcd", array("b","c"), array("x","y","z")) '=> "axyd"
	'@ AB.C.PrintCn AB.C.RP("abcd", array("b","c"), array("x")) '=> "axd"
	'@ AB.C.PrintCn AB.C.RP("abcd", array("b","c"), "-") '=> "a--d"
	'@ *****************************************************************************************

	Public Function RP(Byval Str, Byval FindStr, Byval RepStr)
		On Error Resume Next
		IF IsNull(Str) Or Str="" Then RP="":Exit Function
		If IsArray(FindStr) Then
			Dim i, x, y, m : i = 0 : m = Ubound(FindStr)
			If Err Then : Err.Clear : RP = Str : Exit Function : End If
			If m > 0 Then
				If IsArray(RepStr) Then
					Dim n : n = Ubound(RepStr)
					If Err Then : Err.Clear : RP = Str : Exit Function : End If
					If m >= n Then
						For i = 0 To n
							Str = Replace(Str, FindStr(i), RepStr(i))
						Next
						For i=n+1 To m
							Str = Replace(Str, FindStr(i), "")
						Next
					Else
						For i = 0 To m
							Str = Replace(Str, FindStr(i), RepStr(i))
						Next
					End If
				Else
					For i = 0 To m
						Str = Replace(Str, FindStr(i), RepStr)
					Next
				End If
				RP = Str
			End If
		Else
			If IsArray(RepStr) Then : RP = Str : Exit Function : End If
			'RP = Replace(Str,FindStr,RepStr,1,-1,1)
			RP = Replace(Str,FindStr,RepStr)
		End If
		If Err Then : Err.Clear : RP = Str : End If
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Include filePath
	'@ 返  回:  无返回值
	'@ 作  用:  服务器端动态包含文件
	'==DESC=====================================================================================
	'@ filePath：要包含的文件路径，可以是相对路径、站点绝对路径(以/开头)和硬盘绝对路径(以"盘符:\"开头)
	'@ 此方法实现了ASP服务器端的动态包含，可以完全替换ASP中用<!--#include ... -->包含文件的方法，
	'@ 而且可以根据条件进行动态包含，不会预读任何页面信息。
	'@ 此方法有以下特点：
	'@   1 - 支持动态包含ASP、Html、Txt等一切文本文件（相对路径和绝对路径均可），而且会自动执行其中的ASP语句（< % % >标记内的代码）；
	'@   2 - 支持无限级的ASP原始预包含文件方法<!--#include ... -->，也就是#include中的#include（支持无限级#include）也可以自动包含；
	'@   3 - 自动识别ASP原始预包含文件方法<!--#include ... -->中的相对路径和绝对路径；
	'@   4 - 自动过滤被包含的ASP文件的源代码中出现的@LANGUAGE、@CODEPAGE及Option Explicit等会引起ASP报错的内容。
	'@ 如果要载入不同于当前文件编码的文档，可以先设置 AB.CharSet 属性为相应的编码类型。
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Sub Include(ByVal filePath)
		On Error Resume Next
		AB.Pub.Include filePath
		On Error Goto 0
	End Sub

	Public Sub xInclude(ByVal filePath)
		On Error Resume Next
		AB.Pub.xInclude filePath
		On Error Goto 0
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IncCode filePath
	'@ 返  回:  字符串 # [String]
	'@ 作  用:  获取ASP文件里的ASP代码
	'==DESC=====================================================================================
	'@ filePath：要包含的文件路径，可以是相对路径、站点绝对路径(以/开头)和硬盘绝对路径(以"盘符:\"开头)
	'==DEMO=====================================================================================

	Public Function IncCode(ByVal filePath)
		IncCode = AB.Pub.IncCode(filePath)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IncXCode filePath
	'@ 返  回:  字符串 # [String]
	'@ 作  用:  获取ASP文件里的ASP代码(转成 Abx_s_html 代码)
	'==DESC=====================================================================================
	'@ filePath：要包含的文件路径，可以是相对路径、站点绝对路径(以/开头)和硬盘绝对路径(以"盘符:\"开头)
	'==DEMO=====================================================================================

	Public Function IncXCode(ByVal filePath)
		IncXCode = AB.Pub.IncXCode(filePath)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetInclude filePath
	'@ 返  回:  服务器端包含文件运行的结果
	'@ 作  用:  得到服务器端包含文件的结果
	'==DESC=====================================================================================
	'@ filePath：要包含的文件路径，可以是相对路径、站点绝对路径(以/开头)和硬盘绝对路径(以"盘符:\"开头)
	'@ 此方法和 AB.C.Include 很相似，不同的地方是 : AB.C.Include方法如果包含有HTML内容时会直接输出，
	'@ 而此方法会将包含文件输出的所有HTML内容返回为一个字符串变量。
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function getInclude(ByVal filePath)
		On Error Resume Next
		ExecuteGlobal IncXCode(filePath)
		getInclude = Abx_s_html
		If Err.Number<>0 Then
			AB.setError "(File Not Found: """ & filePath & """)", 2
		End If
		On Error Goto 0
	End Function

	Public Function IncRead(ByVal filePath)
		On Error Resume Next
		IncRead = AB.Pub.IncRead(filePath)
		On Error Goto 0
	End Function

	Public Function Read(ByVal filePath)
		On Error Resume Next
		Read = AB.Pub.Read(filePath)
		On Error Goto 0
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.CLeft(s, m)
	'@ 返  回:  某个分隔符左边部分的字符串 # [String]
	'@ 作  用:  截取用某个特殊字符串分隔的左边部分
	'==Param==============================================================
	'@ s :   原字符串 # [String]
	'@ m :   分隔符 # [String]
	'==DEMO==============================================================
	'@ AB.C.PrintCn AB.C.CLeft("hello:kitty_here", ":") '返回值: hello
	'@ AB.C.PrintCn AB.C.CLeft("hello:kitty_here", "_") '返回值: hello:kitty
	'@ ******************************************************************

	Public Function CLeft(ByVal s, ByVal m)
		CLeft = AB.Pub.LR(s,m,0)
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.CRight(s, m)
	'@ 返  回:  某个分隔符右边部分的字符串 # [String]
	'@ 作  用:  截取用某个特殊字符串分隔的右边部分
	'==Param==============================================================
	'@ s :   原字符串 # [String]
	'@ m :   分隔符 # [String]
	'==DEMO==============================================================
	'@ AB.C.PrintCn AB.C.CRight("hello:kitty_here", ":") '返回值: kitty_here
	'@ AB.C.PrintCn AB.C.CRight("hello:kitty_here", "_") '返回值: here
	'@ ******************************************************************

	Public Function CRight(ByVal s, ByVal m)
		CRight = AB.Pub.LR(s,m,1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RegMatch string, rule
	'@ 语  法:  Set result = AB.C.RegMatch(string, rule)
	'@ 返  回:  Object (ASP对象), 捕获到的匹配Matches集合
	'@ 作  用:  使用此方法可以对字符串中的正则编组进行捕获，返回一个Matches集合，
	'@ 			可以循环此集合，然后用SubMatches集合对匹配的Match对象结果进行操作。
	'==DESC=====================================================================================
	'@ string String (字符串) 待操作的字符串
	'@ rule String (字符串) 包含编组的正则表达式
	'@ result Variable (变量) 返回值，返回的类型将是一个Matches集合
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function RegMatch(ByVal s, ByVal rule)
		o_regex.Pattern = rule
		Set RegMatch = o_regex.Execute(s)
		o_regex.Pattern = ""
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RegReplace string, rule, result
	'@ 返  回:  替换后的字符串
	'@ 作  用:  把参数string中的匹配rule参数中正则表达式规则的字符串替换为参数result中的值
	'==DESC=====================================================================================
	'@ string:  String (字符串) 待替换的字符串
	'@ rule:  	String (字符串) 待替换的正则表达式规则
	'@ result:  String (字符串) 需要替换为的结果
	'==DEMO=====================================================================================
	'@ AB.C.RegReplace("这是个示例abcd","a(bc)?d", "***")
	'@ 返回值: 这是个示例***
	'@ *****************************************************************************************

	Public Function RegReplace(ByVal s, ByVal rule, Byval Result)
		RegReplace = AB.Pub.ReplaceX(s,rule,Result,0)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RegReplaceM string, rule, result
	'@ 返  回:  替换后的字符串
	'@ 作  用:  把参数string中的匹配rule参数中正则表达式规则的字符串替换为参数result中的值
	'==DESC=====================================================================================
	'@ 此方法同 AB.C.RegReplace 方法基本一致，唯一的区别是正则表达式的Multiline(多行)属性为真。
	'@ 在多行模式下，正则表达式将在每一行中匹配结果，包括^（起始）和$（结束）标记。
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function RegReplaceM(ByVal s, ByVal rule, Byval Result)
		RegReplaceM = AB.Pub.ReplaceX(s,rule,Result,1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RegTest string, rule
	'@ 返  回:  布尔值(True或False)
	'@ 作  用:  检测字符串是否满足正则表达式规则
	'==DESC=====================================================================================
	'@ [arg] string : 要检测的字符串
	'@ [arg] rule : 正则表达式规则
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function RegTest(ByVal s, ByVal p)
		If isNul(s) Then RegTest = False : Exit Function
		o_regex.Pattern = p
		RegTest = o_regex.Test(CStr(s))
		o_regex.Pattern = ""
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Test string, rule
	'@ 返  回:  Boolean (布尔值)
	'@ 作  用:  将根据指定的规则验证参数string的合法性
	'@ 			验证通过则返回真(True)，不合法则返回假(False)。
	'==DESC=====================================================================================
	'@ string String (字符串) 待验证的字符串
	'@ rule String (字符串) 可以是正则表达式，也可以是以下字符串：
	'@   "date" - 验证是否为合法的日期格式
	'@   "idcard" - 验证是否为合法的身份证号码
	'@   "english" - 验证是否只包含英文字母
	'@   "chinese" - 验证是否只包含中文字符
	'@   "int-en" - 验证是否只包含英文和数字字符
	'@   "int-en-ch" - 验证是否只包含中英文及数字字符
	'@   "username" - 验证是否是合法的用户名（4-20位，只能是大小写字母数字及下划线且以字母开头）
	'@   "email" - 验证是否是合法的E-mail地址
	'@   "int" - 验证是否为整数
	'@   "number" - 验证是否为数字
	'@   "double" - 验证是否为双精度数字
	'@   "price" - 验证是否为价格格式
	'@   "zip" - 验证是否为合法的邮编
	'@   "qq" - 验证是否为合法的QQ号
	'@   "phone" - 验证是否为合法的电话号码
	'@   "mobile" - 验证是否为合法的手机号码
	'@   "url" - 验证是否为合法的URL地址
	'@   "ip" - 验证是否为合法的IP地址
	'==DEMO=====================================================================================
	'@ AB.C.Test("2008-2-30 12:00","date")	'返回值: True
	'@ AB.C.Test("M20","^\w[1-4][0-9]")	'返回值: True
	'@ *****************************************************************************************

	Public Function [Test](ByVal s, ByVal p)
		Dim Pa
		Select Case Lcase(p)
			Case "date"			[Test] = isDate(s) : Exit Function
			'Case "idcard" 		Pa = "^\d{15}(\d{2}[A-Za-z0-9])?$"	'身份证
			Case "idcard"		[Test] = isIDCard(s) : Exit Function '身份证
			'Case "number"		Pa = "^\d+$" '数字
			Case "number"		[Test] = IsNum(s) : Exit Function
			Case "english"		Pa = "^[A-Za-z]+$" '英文字母
			Case "chinese"		Pa = "^[\u4e00-\u9fa5]+$" '中文
			Case "int-en"		Pa = "^[A-Za-z0-9]" '英文和数字
			Case "int-en-ch" 	Pa = "^[A-Za-z0-9-\u2E80-\u9FA5]" '中英文及数字
			Case "username"		Pa = "^[a-zA-Z]\w{2,19}$"
			'Case "email"		Pa = "^\w+([-+\.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$" '邮箱
			Case "email"		Pa = "^\w+([-+\.]\w+)*@(([\da-zA-Z][\da-zA-Z-]{0,61})?[\da-zA-Z]\.)+([a-zA-Z]{2,4}(?:\.[a-zA-Z]{2})?)$"
			Case "int"			Pa = "^[-\+]?\d+$" '正整数
			Case "double"		Pa = "^[-\+]?\d+(\.\d+)?$" '浮点数
			Case "price"		Pa = "^\d+(\.\d+)?$"
			Case "zip"			Pa = "^\d{6}$" '邮编
			Case "qq"			Pa = "^[1-9]\d{4,9}$"
			'Case "phone"		Pa = "^((\(\d{3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}$" 'Phone
			Case "phone"		Pa = "^((\(\+?\d{2,3}\))|(\+?\d{2,3}\-))?(\(0?\d{2,3}\)|0?\d{2,3}-)?[1-9]\d{4,7}(\-\d{1,4})?$"
			Case "mobile"		Pa = "^(\+?\d{2,3})?0?1(3\d|47|5\d|8[056789])\d{8}$" 'Mobile
			'Case "url"			Pa = "^(http|https|ftp):(\/\/|\\\\)(([\w\/\\\+\-~`@:%])+\.)+([\w\/\\\.\=\?\+\-~`@\':!%#]|(&amp;)|&)+" 'URL地址
			Case "url"			Pa = "^(?:(https|http|ftp|rtsp|mms)://(?:([\w!~\*'\(\).&=\+\$%-]+)(?::([\w!~\*'\(\).&=\+\$%-]+))?@)?)?((?:(?:(?:25[0-5]|2[0-4]\d|(?:1\d|[1-9])?\d)\.){3}(?:25[0-5]|2[0-4]\d|(?:1\d|[1-9])?\d))|(?:(?:(?:[\da-zA-Z][\da-zA-Z-]{0,61})?[\da-zA-Z]\.)+(?:[a-zA-Z]{2,4}(?:\.[a-zA-Z]{2})?)|localhost))(?::(\d{1,5}))?([#\?/].*)?$" 'URL地址
			Case "domain"		Pa = "^(([\da-zA-Z][\da-zA-Z-]{0,61})?[\da-zA-Z]\.)+([a-zA-Z]{2,4}(?:\.[a-zA-Z]{2})?)$"
			'Case "ip"			Pa = "^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$"	'IP
			Case "ip"			Pa = "^((25[0-5]|2[0-4]\d|(1\d|[1-9])?\d)\.){3}(25[0-5]|2[0-4]\d|(1\d|[1-9])?\d)$"
			Case "key"			Pa = "^(([a-z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\''\""]*)|.{0,5})$|\s"	'键盘上有的字符
			Case "imgurl"		Pa = "^((http|https|ftp):(\/\/|\\\\)(([\w\/\\\+\-~`@:%])+\.)+([\w\/\\\.\=\?\+\-~`@\':!%#]|(&amp;)|&)+|\/([\w\/\\\.\=\?\+\-~`@\':!%#]|(&amp;)|&)+)\.(jpeg|jpg|gif|png|bmp)$"	'图片地址
			Case "time" 		Pa = "^(?=\d)(?:(?!(?:1582(?:\.|-|\/)10(?:\.|-|\/)(?:0?[5-9]|1[0-4]))|(?:1752(?:\.|-|\/)0?9(?:\.|-|\/)(?:0?[3-9]|1[0-3])))(?=(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:\d\d)(?:[02468][048]|[13579][26]))\d0?2\d29)|(?:\d{4}\d(?!(?:0?[2469]|11)\d31)(?!0?2(?:\.|-|\/)(?:29|30))))(\d{4})([-\/.])(0?\d|1[012])\2((?!00)[012]?\d|3[01])(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aapp][mm]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$"	'时间
			Case "safe" 		Pa = "^[a-zA-Z0-9\_\-]+$"	'数字、大小字母、下划线、横线
			Case Else Pa = p
		End Select
		[Test] = RegTest(CStr(s),Pa)
	End Function

	'@ *************************************************************************************************
	'@ 过程名:  AB.C.Str string, array
	'@ 返  回:  重新组合后的新字符串
	'@ 作  用:  可以将一个包含复杂变量的字符串通过直观的方式呈现。
	'@ 			string参数中包含的{1}、{2}等占位符将被替换为array参数中相应的元素的值，
	'@ 			并返回一个新的字符串。
	'==DESC=============================================================================================
	'@ string  	: String (字符串) 包含占位符的字符串
	'@ array	: Array (数组) 占位符的实际值，{1}对应数组的第1个元素，以此类推
	'==DEMO=============================================================================================
	'@ AB.C.Str("<{4}><a href=""/{2}.html"">{3}.{1}</a></{4}>",Array("李一","user/liyi","Miss","div"))
	'@ 返回值: <div><a href="/user/liyi.html">Miss.李一</a></div>
	'@ *************************************************************************************************

	Public Function Str(ByVal s, ByVal v)
		Str = FormatString(s, v, 1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.JS string
	'@ 返  回:  一段由<script>标签包含的javascript代码
	'@ 作  用:  返回一段标准的javascript代码片断，可用于在浏览器中输出
	'==DESC=====================================================================================
	'@ string : String (字符串) javascript代码语句
	'==DEMO=====================================================================================
	'@ AB.C.JS "alert('删除成功！');"
	'@ 返回值: AB.C.Print("<script type=""text/javascript"">alert('删除成功！');</script>")
	'@ *****************************************************************************************

	Public Sub Js(ByVal s)
		Print JsCode(s)
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.JsCode String
	'@ 返  回:  一段由<script>标签包含的javascript代码
	'@ 作  用:  返回一段标准的javascript代码片断，可用于在浏览器中输出
	'==DESC=====================================================================================
	'@ String :   javascript代码 # [String]
	'==DEMO=====================================================================================
	'@ AB.C.JsCode("alert('hit me!');")
	'@ 结果: <script type="text/javascript">alert('hit me!');</script>
	'@ *****************************************************************************************

	Public Function JsCode(ByVal s)
		JsCode = Str("<{1} type=""text/java{1}"">{2}{3}{4}{2}</{1}>{2}", Array("sc"&"ript",vbCrLf,vbTab,s))
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Alert string
	'@ 返  回:  输出 javascript 弹出信息并返回到上一页
	'@ 作  用:  弹出一个javascript信息框并返回至前一页(history.back)
	'==DESC=====================================================================================
	'@ String :   要输出的弹出信息内容 # [String]
	'==DEMO=====================================================================================
	'@ AB.C.Alert "输入信息错误！"
	'@ 结果: <script type="text/javascript">alert('输入信息错误！');history.go(-1);</script>
	'@ *****************************************************************************************

	Public Sub Alert(ByVal s)
		Print JsCode(Str("alert('{1}');history.go(-1);",JsEncode(s)))
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.MsgBox string
	'@ 别  名:  AB.C.JsAlert string
	'@ 返  回:  输出 javascript 弹出信息
	'@ 作  用:  弹出一个javascript信息框
	'==DESC=====================================================================================
	'@ String :   要输出的弹出信息内容 # [String]
	'==DEMO=====================================================================================
	'@ AB.C.MsgBox "输入信息错误！"
	'@ 结果: <script type="text/javascript">alert('输入信息错误！');</script>
	'@ *****************************************************************************************

	Public Sub JsAlert(ByVal s)
		Print JsCode(Str("alert('{1}');",JsEncode(s)))
	End Sub
	Public Sub MsgBox(ByVal s)
		Print JsCode(Str("alert('{1}');",JsEncode(s)))
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.AlertUrl string, url
	'@ 返  回:  无返回值
	'@ 作  用:  弹出一个javascript信息框并返回至前一页(history.back)
	'==DESC=====================================================================================
	'@ String	: 要弹出显示的信息 # [String]
	'@ Url 		: 确认信息后要转到的页面地址 # [String]
	'==DEMO=====================================================================================
	'@ AB.C.AlertUrl "信息错误！请重新输入", "../info/add.asp"
	'@ 结果: <script type="text/javascript">alert('信息错误！请重新输入');location.href='../info/add.asp';</script>
	'@ *****************************************************************************************

	Public Sub AlertUrl(ByVal s, ByVal u)
		Print JsCode(Str("alert('{1}');location.href='{2}';",Array(JsEncode(s),u)))
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.ConfirmUrl string, okUrl, cancelUrl
	'@ 返  回:  无返回值
	'@ 作  用:  服务器端输出 javascript 确认消息框并根据选择转到URL
	'==DESC=====================================================================================
	'@ string 		: String (字符串) : 要弹出显示的询问信息
	'@ okUrl 		: String (字符串) : 用户选择“确认”后要转到的网址
	'@ cancelUrl 	: String (字符串) : 用户选择“取消”后要转到的网址
	'==DEMO=====================================================================================
	'@ AB.C.ConfirmUrl "添加成功！要继续添加吗？", "add.asp", "list.asp"
	'@ *****************************************************************************************

	Public Sub ConfirmUrl(ByVal s, ByVal t, ByVal f)
		Print JsCode(Str("location.href=confirm('{1}')?'{2}':'{3}';",Array(JsEncode(s),t,f)))
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.JsEncode String
	'@ 返  回:  经过转义的字符串
	'@ 作  用:  把一个字符串中的特殊字符转义为安全的JavaScript字符串
	'==DESC=====================================================================================
	'@ String : 待转义的字符串 # [String]
	'==DEMO=====================================================================================
	'@ AB.C.JSEncode("The Path is : '\test\path'")
	'@ 返回值: The Path is : \'\\test\\path\'
	'@ *****************************************************************************************

	Public Function JsEncode(ByVal s)
		If isNul(s) Then JsEncode = "" : Exit Function
		Dim arr1, arr2, i, j, c, p, t
		arr1 = Array(&h27,&h22,&h5C,&h2F,&h08,&h0C,&h0A,&h0D,&h09)
		arr2 = Array(&h27,&h22,&h5C,&h2F,&h62,&h66,&h6E,&h72,&h74)
		For i = 1 To Len(s)
			p = True
			c = Mid(s, i, 1)
			For j = 0 To Ubound(arr1)
				If c = Chr(arr1(j)) Then
					t = t & "\" & Chr(arr2(j))
					p = False
					Exit For
				End If
			Next
			If p Then
				Dim a
				a = strAsc(c)
				If a > 31 And a < 127 Then
					t = t & c
				ElseIf a > -1 Or a < 65535 Then
					t = t & "\u" & String(4 - Len(Hex(a)), "0") & Hex(a)
				End If
			End If
		Next
		JsEncode = t
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.ASCII String
	'@ 返  回:  String : "&"开头的字符串
	'@ 作  用:  把字符串转换为以 "&" 开头的HTML实体代码
	'==DESC==============================================================
	'@ String : 原字符串 # [String]
	'==DEMO==============================================================
	'@ AB.C.ASCII("I Like") '返回值: &#73;&#32;&#76;&#105;&#107;&#101;
	'@ ******************************************************************

	Public Function ASCII(s)
		If isNul(s) Then ASCII = "" : Exit Function
		Dim tmp,i,t
		For i = 1 To len(s)
			t = strAsc(Mid(s,i,1))
			If t<0 Then t = t + 65536
			tmp = tmp & "&#" & t & ";"
		Next
		ASCII = tmp
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.RR url
	'@ 返  回:  无返回值
	'@ 作  用:  URL跳转(Response.Redirect的缩写)
	'==DESC==============================================================
	'@ url : 跳转的地址 # [String]
	'==DEMO==============================================================
	'@ AB.C.RR "http://www.baidu.com/" 等同于 Response.Redirect "http://www.baidu.com/"
	'@ ******************************************************************

	Public Sub RR(ByVal u)
		Response.Redirect(u)
	End Sub

	'@ ******************************************************************
	'@ 过程名:  AB.C.AddHeader HeaderName, HeaderText
	'@ 返  回:  无返回值
	'@ 作  用:  增加一个HTML头(header)
	'==DESC==============================================================
	'@ HeaderName : 头变量名称 # [String]
	'@ HeaderText : 头变量初始值 # [String]
	'==DEMO==============================================================
	'@ 文件下载，指定默认名:
	'@ AB.C.AddHeader "Content-Type", "application/x-msdownload"
	'@ AB.C.AddHeader "Content-Disposition", "attachment;filename=文件名.rar"
	'@ 刷新页面:
	'@ AB.C.AddHeader "refresh","3;url=http://www.baidu.com"
	'@ ******************************************************************

	Public Function AddHeader(s, p)
	    Response.AddHeader s, p
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.Redirect strURL, strT, strTip
	'@ 返  回:  无返回值
	'@ 作  用:  通过浏览器头部实现跳转
	'==DESC==============================================================
	'@ strURL : 要跳转的地址 # [String]
	'@ strT : 跳转时间间隔 # [String]
	'@ strTip : 跳转提示文字 # [String]
	'==DEMO==============================================================
	'@ AB.C.Redirect "/index.asp",3,"操作成功"
	'@ AB.C.Redirect "http://www.baidu.com",0,""
	'@ ******************************************************************

	Public Function Redirect(strURL,strT,strTip)
		On Error Resume Next
		Dim T:IF CLng(strT)>0 Then T=CLng(strT)
		IF T>0 Then:T=CLng(T):Else:T=0:End IF
		Response.AddHeader "REFRESH",""&T&";url=" & strURL
		Pesponse.Clear
		IF Not IsNull(strTip) and strTip<>"" Then
			Print "<span style=""font-size:12px;"">"&strTip&"，正在跳转...</span>"
			Print "<span style=""font-size:12px;color:#888;"">&nbsp;若"&T&"秒后没有跳转，请点击<a href="""& strURL &""" style=""color:#0000ff;text-decoration:underline;"">这里</a></span>"
		End IF
		Response.End()
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.NoCache()
	'@ 返  回:  无返回值
	'@ 作  用:  强制页面不保存在浏览器的缓存中。
	'@ 			下次访问此页面时，将再次从服务器获取而不是从浏览器缓存中
	'==DESC=====================================================================================
	'@ 无参数
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Sub NoCache()
		Response.Buffer = True
		Response.Expires = 0
		Response.ExpiresAbsolute = Now() - 1
		Response.CacheControl = "no-cache"
		Response.AddHeader "Expires",Date()
		Response.AddHeader "Pragma","no-cache"
		'Response.AddHeader "Cache-Control","no-cache,private, post-check=0, pre-check=0, max-age=0"
		Response.AddHeader "Cache-Control","private, no-cache, must-revalidate"
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.strChr string
	'@ 返  回:  (String) 返回与指定的 ANSI 字符代码相对应的字符
	'@ 作  用:  用于取代UTF-8版本和GBK版 用到的ChrW函数还是Chr函数等冲突问题。
	'==DESC=====================================================================================
	'@ 参数 string : 字符串
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.strChr(97) '返回: a
	'@ *****************************************************************************************

	Public Function strChr(ByVal s)
		If UCase(AB.CharSet)="UTF-8" Then
			strChr = ChrW(s)
		Else
			strChr = Chr(s)
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.strAsc string
	'@ 返  回:  (Integer) 获取字符串的ASCII码
	'@ 作  用:  用于取代UTF-8版本和GBK版获取字符串ASCII码用到的AscW函数还是Asc函数等冲突问题。
	'==DESC=====================================================================================
	'@ 参数 string : 字符串
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.strAsc("a") '返回: 97
	'@ *****************************************************************************************

	Public Function strAsc(ByVal s)
		If UCase(AB.CharSet)="UTF-8" Then
			strAsc = AscW(s)
		Else
			strAsc = Asc(s)
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.StrLen string
	'@ 返  回:  字符串真实长度(字符宽度)
	'@ 作  用:  计算字符串宽度（汉字则宽度为2, 英文字母及数字为1）
	'==DESC=====================================================================================
	'@ 参数 string : 字符串
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.strLen("abcdefg中文字符") '返回: 15
	'@ *****************************************************************************************

	Public Function StrLen(Byval s)
		AB.Use "Char"
		StrLen = AB.Char.StrLen(s)
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.CutStr string, charNumber[:separator]
	'@ 返  回:  从左边截取指定数量的字符串，
	'@			并以自定义的符号代替未显示部分 # [String]
	'@ 作  用:  截取字符串的左边指定字数的部分，
	'@			右边省略的部分以指定的符号（缺省为省略号“…”）代替
	'@			双字节字符（比如中文）算2个字符
	'==Param==============================================================
	'@ s 		: 	待截取的字符串 # [String]
	'@ strLen 		: 	要保留的字数(包含 separator )
	'==DEMO==============================================================
	'@ AB.C.CutStr("This is a test 字符串", 10) '返回值: This is …
	'@ AB.C.CutStr("This is a test 字符串", "10:~~") '返回值: This is ~~
	'@ AB.C.CutStr("This is a test 字符串", "17:") '返回值: This is a test 字
	'@ ******************************************************************

	Public Function CutStr(ByVal s, ByVal strLen)
		If isNul(s) Then CutStr = "" : Exit Function
		Dim slen : slen = strLen
		If isNul(slen) or slen = "0" Then CutStr = s : Exit Function
		Dim lg,t,i,j,d,f,n
		s = Replace(s,vbCrLf,"")
		s = Replace(s,vbTab,"")
		lg = len(s) : t = 0 : d = strChr(8230) : f = Abx_Param(slen)
		If Instr(slen,":")>0 Then
			d = IfHas(f(1),"")
		End If
		slen = Int(f(0)) : f = "" : n = 0
		For j = 1 To Len(d)
			n = IIF(Abs(strAsc(Mid(d,j,1)))>255, n+2, n+1)
		Next
		slen = slen - n
		For i = 1 to lg
			t = IIF(Abs(strAsc(Mid(s,i,1)))>255, t+2, t+1)
			If t >= slen Then
				f = Left(s,i) & d
				Exit For
			Else
				f = s
			End If
		Next
		CutStr = f
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.HtmlFormat String
	'@ 返  回:  经过格式化的字符串
	'@ 作  用:  仅把字符串中的换行符和空格替换为浏览器可以显示的标签，
	'@ 			其它的HTML标签不作处理
	'==DESC=====================================================================================
	'@ String :   待格式化的HTML文本 # [String]
	'==DEMO=====================================================================================
	'@ AB.C.HtmlFormat("这是一段<b>测试</b>"&vbCrLf&"  <font color=""red"">文本</font>")
	'@ 返回值: 这是一段<b>测试</b>用的<br />&nbsp;&nbsp;<font color="red">文本</font>
	'@ *****************************************************************************************

	Public Function HtmlFormat(ByVal s)
		If Has(s) Then
			Dim m,Match : Set m = RegMatch(s, "<([^>]+)>")
			For Each Match In m
				 s = Replace(s, Match.SubMatches(0), regReplace(Match.SubMatches(0), "\s+", Chr(0)))
			Next
			Set m = Nothing
			s = Replace(s, Chr(32), "&nbsp;")
			s = Replace(s, Chr(9), "&nbsp;&nbsp; &nbsp;")
			s = Replace(s, Chr(0), " ")
			s = regReplace(s, "(<[^>]+>)\s+", "$1")
			s = Replace(s, vbCrLf, "<br />")
		End If
		HtmlFormat = s
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.HtmlEncode String
	'@ 返  回:  经过转换的html字符串
	'@ 作  用:  HTML加码函数,加码参数中的字符串，以方便阅读的HTML格式显示出来
	'==DESC==============================================================
	'@ String :   待转换的字符串 # [String]
	'==DEMO==============================================================
	'@ AB.C.HtmlEncode("这是一段<b>测试</b>文字。" & vbCrLf & "谢谢")
	'@ 返回值: 这是一段&lt;b&gt;测试&lt;/b&gt;文字。<br />谢谢
	'@ ******************************************************************

	Public Function HtmlEncode(ByVal s)
		If Has(s) Then
			s = Replace(s, Chr(38), "&#38;")
			s = Replace(s, "<", "&lt;")
			s = Replace(s, ">", "&gt;")
			s = Replace(s, Chr(39), "&#39;")
			s = Replace(s, Chr(32), "&nbsp;")
			s = Replace(s, Chr(34), "&quot;")
			s = Replace(s, Chr(9), "&nbsp;&nbsp; &nbsp;")
			s = Replace(s, vbCrLf, "<br />")
		End If
		HtmlEncode = s
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.HtmlDecode String
	'@ 返  回:  可识别的html代码
	'@ 作  用:  HTML解码函数,将字符串中的特殊字符转换为可识别的html代码
	'==DESC==============================================================
	'@ String :   待转换的字符串 # [String]
	'==DEMO==============================================================
	'@ AB.C.HtmlDecode("这是一段&lt;em&gt;测试&lt;/em&gt;文字。<br />谢谢")
	'@ 返回值: 这是一段<em>测试</em>文字。<br />谢谢
	'@ ******************************************************************

	Public Function HtmlDecode(ByVal s)
		If Has(s) Then
			s = regReplace(s, "<br\s*/?\s*>", vbCrLf)
			s = Replace(s, "&nbsp;&nbsp; &nbsp;", Chr(9))
			s = Replace(s, "&quot;", Chr(34))
			s = Replace(s, "&nbsp;", Chr(32))
			s = Replace(s, "&#39;", Chr(39))
			s = Replace(s, "&apos;", Chr(39))
			s = Replace(s, "&gt;", ">")
			s = Replace(s, "&lt;", "<")
			s = Replace(s, "&amp;", Chr(38))
			s = Replace(s, "&#38;", Chr(38))
		End If
		HtmlDecode = s
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.HtmlFilter String
	'@ 返  回:  经过处理后的字符串
	'@ 作  用:  过滤参数字符串中的所有HTML标签，返回纯文本
	'==DESC==============================================================
	'@ String :   待过滤的字符串 # [String]
	'==DEMO==============================================================
	'@
	'@ ******************************************************************

	Public Function HtmlFilter(ByVal s)
		If Has(s) Then
			If isNul(s) Then HtmlFilter = "" : Exit Function
			s = regReplace(s,"<[^>]+>","")
			s = Replace(s, ">", "&gt;")
			s = Replace(s, "<", "&lt;")
		End If
		HtmlFilter = s
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.RegEncode String
	'@ 返  回:  字符串进行正则形式处理
	'@ 作  用:  对字符串含有正则表达式某特殊字符进行转义
	'==DESC==============================================================
	'@ String :   待处理的字符串 # [String]
	'==DEMO==============================================================
	'@
	'@ ******************************************************************

	Public Function RegEncode(ByVal s)
		Dim re,i
		re = Split("\,$,(,),*,+,.,[,?,^,{,|,:,<",",")
		For i = 0 To Ubound(re)
			s = Replace(s,re(i),"\"&re(i))
		Next
		RegEncode = s
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.SetCookie cooName[>keyName], cooValue, cooConfig
	'@ 返  回:  无返回值
	'@ 作  用:  设置一个Cookies值
	'@ 			此方法将设置一个Cookies的值或一个Cookies集合的值，并可以指定它的存活期限、路径、域及安全选项。
	'==PARAMSafe=====================================================================================
	'@ cooName String (字符串)
	'@   Cookies或者Cookies集合的名称
	'@ keyName(可选) String (字符串)
	'@   Cookies集合中关键字的名称
	'@ cooValue "" (空字符串) 或 String (字符串)
	'@   Cookies的值，如果此参数为空，则仅设置cooConfig指定的值
	'@ cooConfig Array (数组) 或 Boolean (布尔值) 或 Datetime (时间日期) 或 Integer (整数) 或 String (字符串)
	'@   Cookies的存活期限、路径、域及安全设置，用数组参数可设置多个选项。可以是以下值：
	'@   数值或时间值 - 设置Cookies的存活期限，
	'@     如果是时间值则表示此Cookies到指定的时间失效，
	'@     如果是数字则表示此Cookies可以存活的时间长度(以分钟为单位)，
	'@     如果为数字0则表示此Cookies到浏览器关闭时失效。
	'@   域名字符串 - 设置Cookies的有效域名。
	'@   相对路径字符串 - 设置Cookies的有效路径。
	'@   布尔值 - 设置Cookies的安全性。
	'@   数组 - 可以同时设置以上4种Cookies选项。
	'==DEMO=====================================================================================
	'@ '设置一个30分钟后失效的Cookies
	'@ AB.C.SetCookie "MyServerIP", "192.168.0.1", 30
	'@ '设置一个到2009年9月9日上午10点失效的Cookies
	'@ AB.C.SetCookie "MyServerIP", "192.168.0.1", "2009-9-9 10:00"
	'@ '设置一个仅对域ambox.cn有效的Cookies
	'@ AB.C.SetCookie "UserId", "3568", "ambox.it"
	'@
	'@ 当然用数组来设置多个选项是不错的选择：
	'@ AB.C.SetCookie "AboxInfo", "", Array("/bbs",False)
	'@ AB.C.SetCookie "AboxInfo>userName", "lajox", Array("ambox.it","2009-2-28 23:59:59",True)
	'@ AB.C.SetCookie "AboxInfo>userLevel", 0, ""
	'@ '上面的用法等同于下面的传统设置Cookies方式：
	'@ Response.Cookies("AboxInfo").Path = "/bbs"
	'@ Response.Cookies("AboxInfo").Secure = False
	'@ Response.Cookies("AboxInfo")("userName") = "lajox"
	'@ Response.Cookies("AboxInfo").Expires = "2009-2-28 23:59:59"
	'@ Response.Cookies("AboxInfo").Domain = "ambox.it"
	'@ Response.Cookies("AboxInfo").Secure = True
	'@ Response.Cookies("AboxInfo")("userLevel") = 0
	'@ *****************************************************************************************

	Public Sub SetCookie(ByVal cooName, ByVal cooValue, ByVal cooCfg)
		Dim n,i,cExp,cDomain,cPath,cSecure
		If isArray(cooCfg) Then
			For i = 0 To Ubound(cooCfg)
				If isDate(cooCfg(i)) Then
					cExp = cDate(cooCfg(i))
				ElseIf RegTest(cooCfg(i),"int") Then
					If cooCfg(i)<>0 Then cExp = Now()+Int(cooCfg(i))/60/24
				ElseIf RegTest(cooCfg(i),"domain") or RegTest(cooCfg(i),"ip") Then
					cDomain = cooCfg(i)
				ElseIf Instr(cooCfg(i),"/")>0 Then
					cPath = cooCfg(i)
				ElseIf cooCfg(i)="True" or cooCfg(i)="False" Then
					cSecure = cooCfg(i)
				End If
			Next
		Else
			IF Not IsNull(cooCfg) and Trim(cooCfg)<>"" Then
				If isDate(cooCfg) Then
					cExp = cDate(cooCfg)
				ElseIf RegTest(cooCfg,"int") Then
					If cooCfg<>0 Then cExp = Now()+Int(cooCfg)/60/24
				ElseIf RegTest(cooCfg,"domain") or RegTest(cooCfg,"ip") Then
					cDomain = cooCfg
				ElseIf Instr(cooCfg,"/")>0 Then
					cPath = cooCfg
				ElseIf cooCfg = "True" or cooCfg = "False" Then
					cSecure = cooCfg
				End If
			End IF
		End If
		If Has(cooValue) Then
			If AB.CookieEncode Then
				AB.E.Use("Aes") : cooValue = AB.E.Aes.E(cooValue)
			End If
		End If
		If Instr(cooName,">")>0 Then
			n = CRight(cooName,">")
			cooName = CLeft(cooName,">")
			Response.Cookies(cooName)(n) = cooValue
		Else
			Response.Cookies(cooName) = cooValue
		End If
		If Has(cExp) Then Response.Cookies(cooName).Expires = cExp
		If Has(cDomain) Then Response.Cookies(cooName).Domain = cDomain
		If Has(cPath) Then Response.Cookies(cooName).Path = cPath
		If Has(cSecure) Then Response.Cookies(cooName).Secure = cSecure
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Cookie name[>subName][:type[separator]][:default]
	'@ 返  回:  如果有分隔符，则返回数组；如果没有分隔符，则返回经过处理的字符串
	'@ 作  用:  安全获取一个Cookies值
	'==PARAM=====================================================================================
	'@ name String (字符串)
	'@   要获取的参数名，如省略其它参数则相当于原始的Request.Cookies
	'@ subName(可选) String (字符串)
	'@   如不省略此参数，则相当于取Request.Cookies(name)(subName)的值
	'@ type(可选) String (字符串)
	'@   可以是以下字符串：
	'@    "s"  - 表示name是字符串类型的值，会自动处理其中的单引号(')为双单引号('')
	'@    "n"  - 表示name是数值型的值，会验证是否为数值
	'@    "d"  - 表示name是日期型的值，会验证是否为日期
	'@    "na" - 表示name是数值型的值，如果name验证不是数字，则会弹出alert警告框并返回前页
	'@    "da" - 表示name是日期型的值，如果name验证不是日期，则会弹出alert警告框并返回前页
	'@    "ne" - 表示name是数值型的值，如果name验证不是数字，则抛出用户错误信息
	'@   "de" - 表示name是日期型的值，如果name验证不是日期，则抛出用户错误信息
	'@ separator(可选) String (字符串)
	'@   是由此字符串(特殊符号)隔开的序列，如不省略则会逐个检查 name 串中的值，并返回一个数组
	'@ default(可选) String (字符串)
	'@   如果 name 为空或按 type 检查不符合数值/日期要求，则赋给此默认值；序列则逐个赋值
	'@
	'@ 此方法可以返回一个经过处理的安全的Request.Cookies值或Cookies集合中的某一项值，
	'@ 可以用于拼接SQL字符串而不会产生注入问题。
	'@ 如果你想到得到未经处理的原始值，不带任何参数就可以了。
	'@ 如果用 AB.CookieEncode 设置了Cookies加密，则只能用该方法才能获取并解密Cookies数据。
	'==DEMO=====================================================================================
	'@ Dim UserName, SitePath
	'@ UserName = AB.C.Cookie("UserName")    '等同于 Request.Cookies("UserName")
	'@ SitePath = AB.C.Cookie("MySite>Path") '等同于 Request.Cookies("Mysite")("Path")
	'@ '同时，该方法也可以使用 AB.C.Get 和 AB.C.Post 方法的参数形式，如：
	'@ AB.C.Print AB.C.Cookie("MySite>MasterId:n:1")
	'@ *****************************************************************************************

	Public Function Cookie(ByVal s)
		Dim p,t,coo
		If Instr(s,">") > 0 Then
			p = CLeft(s,">")
			s = CRight(s,">")
		End If
		If Instr(s,":")>0 Then
			t = CRight(s,":")
			s = CLeft(s,":")
		End If
		If Has(p) And Has(s) Then
			If Response.Cookies(p).HasKeys Then
				coo = Request.Cookies(p)(s)
			End If
		ElseIf Has(s) Then
			coo = Request.Cookies(s)
		Else
			Cookie = "" : Exit Function
		End If
		If isNul(coo) Then Cookie = "": Exit Function
		If  AB.CookieEncode Then
			AB.E.Use("Aes") : coo = AB.E.Aes.D(coo)
		End If
		Cookie = Safe(coo,t)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RemoveCookie cookieName[:keyName]
	'@ 返  回:  无返回值
	'@ 作  用:  删除一个Cookies值
	'==PARAM=====================================================================================
	'@ cookieName String (字符串)
	'@   要删除的Cookies或者Cookies集合的名称
	'@ keyName(可选) String (字符串)
	'@   要删除的Cookies集合中关键字名称
	'@ 删除一个指定名称的Cookies值，
	'@ 如果keyName参数不为空且cookieName是一个集合，则只删除Cookies内相对应的关键字值。
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Sub RemoveCookie(ByVal s)
		Dim p,t
		If Instr(s,">") > 0 Then
			p = CLeft(s,">")
			s = CRight(s,">")
		End If
		If Has(p) And Has(s) Then
			If Response.Cookies(p).HasKeys Then
				Response.Cookies(p)(s) = Empty
			End If
		ElseIf Has(s) Then
			Response.Cookies(s) = Empty
			Response.Cookies(s).Expires = Now()
		End If
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.HasCookie(key, subkey)
	'@ 返  回:  布尔值
	'@ 作  用:  检查是否有Cookies值
	'==PARAM=====================================================================================
	'@ key String (字符串)
	'@   检测的主键名
	'@ subkey String (字符串)
	'@   检测的子键名
	'==DEMO=====================================================================================
	'@ Response.Cookies("person")("gender") = "男"
	'@ AB.C.PrintCn AB.C.HasCookie("person1234","") '返回 False
	'@ AB.C.PrintCn AB.C.HasCookie("person","") '返回 True
	'@ AB.C.PrintCn AB.C.HasCookie("person","gender") '返回 True
	'@ *****************************************************************************************

	Public Function HasCookie(ByVal p, ByVal t)
		Dim bool : bool = False
		If Trim(t)<>"" Then
			If Not Request.Cookies(p).HasKeys Then
				bool = False
			Else
				For Each key In Request.Cookies(p)
					If key=t Then
						If Request.Cookies(p)(t)<>"" Then
							bool = True
							Exit For
						End If
					End If
				Next
			End If
		Else
			If Request.Cookies(p).HasKeys Then
				bool = True
			Else
				If Request.Cookies(p)<>"" Then
					bool = True
				End If
			End If
		End If
		HasCookie = bool
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Safe(name,type[separator][:default])
	'@ 返  回:  如果有分隔符，则返回数组；如果没有分隔符，则返回经过处理的字符串。
	'@ 			返回值会根据不同的 type 参数值会进行不同的处理
	'@ 作  用:  安全化值
	'==Param====================================================================================
	'@
	'==DEMO=====================================================================================
	'@ AB.C.Safe("这个字符串'包含了单引号","s")
	'@ 结果: 这个字符串''包含了单引号
	'@ *****************************************************************************************

	Public Function Safe(ByVal s, ByVal t)
		Dim spl,d,l,li,i,tmp,arr() : l = False
		If Instr(t,":")>0 Then
			d = CRight(t,":") : t = CLeft(t,":")
		End If
		If Instr(",sa,da,na,se,de,ne,", "," & Left(LCase(t),2) & ",")>0 Then
			If Len(t)>2 Then
				spl = Mid(t,3) : t = LCase(Left(t,2)) : l = True
			End If
		ElseIf Instr("sdn", Left(LCase(t),1))>0 Then
			If Len(t)>1 Then
				spl = Mid(t,2) : t = LCase(Left(t,1)) : l = True
			End If
		ElseIf Has(t) Then
			spl = t : t = "" : l = True
		End If
		li = Split(s,spl)
		If l Then Redim arr(Ubound(li))
		For i = 0 To Ubound(li)
			If i<>0 Then tmp = tmp & spl
			Select Case t
				Case "s","sa","se"
					If isNul(li(i)) Then li(i) = d
					tmp = tmp & Replace(li(i),"'","''")
					If l Then arr(i) = Replace(li(i),"'","''")
				Case "d","da","de"
					If t = "da" Then
						If Not isDate(li(i)) And Has(li(i)) Then Alert("不正确的日期值！")
					ElseIf t = "de" Then
						If Not isDate(li(i)) And Has(li(i)) Then [Error].Throw("不正确的日期值！")
					End If
					tmp = IIF(isDate(li(i)), tmp & li(i), tmp & d)
					If l Then arr(i) = IIF(isDate(li(i)), li(i), d)
				Case "n","na","ne"
					If t = "na" Then
						If Not isNumeric(li(i)) And Has(li(i)) Then Alert("不正确的数值！")
					ElseIf t = "ne" Then
						If Not isNumeric(li(i)) And Has(li(i)) Then [Error].Throw("不正确的数值！")
					End If
					tmp = IIF(isNumeric(li(i)), tmp & li(i), tmp & d)
					If l Then arr(i) = IIF(isNumeric(li(i)), li(i), d)
				Case Else
					tmp = IIF(isNul(li(i)), tmp & d, tmp & li(i))
					If l Then arr(i) = IIF(isNul(li(i)), d, li(i))
			End Select
			If l Then
				If isNul(arr(i)) Then arr(i) = Empty
			End If
		Next
		If isNul(tmp) Then tmp = Empty
		Safe = IIF(l,arr,tmp)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.HasApp appName
	'@ 返  回:  Boolean
	'@ 作  用:  检查是否存在缓存名为 appName 的缓存
	'==PARAM=====================================================================================
	'@ appName String (字符串)
	'==DEMO=====================================================================================
	'@ If AB.C.HasApp("mycache") Then AB.Trace AB.C.GetApp("mycache")
	'@ *****************************************************************************************

	Public Function HasApp(ByVal AppName)
		HasApp = False
		For Each i In Application.Contents
			If i = AppName Then
				HasApp = True
				Exit For
			End If
		Next
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.SetApp appName, appData
	'@ 返  回:  void
	'@ 作  用:  删除一个Cookies值
	'==PARAM=====================================================================================
	'@ appName String (字符串)
	'@   缓存名称
	'@ appData Anything (任意值)
	'@   缓存数据
	'@ 调用此方法将设置一个缓存记录的值。
	'@ (缓存(Application)是一种所有用户均可访问的全局变量，有点类似于所有用户共同的Session)。
	'==DEMO=====================================================================================
	'@ Dim rs
	'@ Set rs = AB.db.GetRecord("Users:Count(UID)","Online = 1","")
	'@ AB.C.SetApp "OnlineCount", rs(0)
	'@ AB.db.C(rs)
	'@ *****************************************************************************************

	Public Sub SetApp(ByVal AppName,ByRef AppData)
		Application.Lock
		If IsObject(AppData) Then
			Set Application(AppName) = AppData
		Else
			Application(AppName) = AppData
		End If
		Application.UnLock
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetApp appName
	'@ 返  回:  Object (ASP对象) （缓存项目的值，可能是任何可以存入缓存的类型）
	'@ 作  用:  获取一个App值
	'==PARAM=====================================================================================
	'@ appName : String (字符串) 缓存项目的名称
	'@ 此方法将返回一个指定名称的缓存(Application)的项目值。
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function GetApp(ByVal AppName)
		If isNul(AppName) Then GetApp = Empty : Exit Function
		If IsObject(Application(AppName)) Then
			Set GetApp = Application(AppName)
		Else
			GetApp = Application(AppName)
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RemoveApp appName
	'@ 返  回:  void
	'@ 作  用:  删除一个App值
	'==PARAM=====================================================================================
	'@ appName : String (字符串) 要删除的Application的名称
	'@ 此方法将删除一个指定名称的缓存记录。
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Sub RemoveApp(ByVal AppName)
		Application.Lock
		Application(AppName) = Empty
		Application.UnLock
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RemoveAppAll
	'@ 返  回:  void
	'@ 作  用:  清空删除所有App值
	'==PARAM=====================================================================================
	'@ none
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Sub RemoveAppAll()
        Application.Lock
        Application.Contents.RemoveAll()
        Application.UnLock
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Rand(s,p)
	'@ 返  回:  获取随机数
	'@ 作  用:  用于获取随机数
	'==PARAM=====================================================================================
	'@ s : 如果p为数字(p>s)时, s表示最小数, p表示最大数，产生的随机数在s ~ p之间变动
	'@ p : 当p为字符串时，表示自定义随机内容，而s则表示随机位数
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.Rand(8,"") '输出8位随机字符串
	'@ AB.C.Print AB.C.Rand(8,"0123456789") '输出8位随机数字
	'@ AB.C.Print AB.C.Rand(1,99) '输出1~99之间的随机数
	'@ *****************************************************************************************

	Public Function Rand(ByVal s, ByVal p)
		If IsNum(s) and IsNum(p) Then
			Dim min,max : min = s : max = p
			Randomize(Timer) : Rand = Int((max - min + 1) * Rnd + min)
		Else
			Dim length,allowStr : length = s : allowStr = p
			If isNul(allowStr) Then allowStr = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
			Dim i
			For i = 1 To length
				Randomize(Timer) : Rand = Rand & Mid(allowStr, Int(Len(allowStr) * Rnd + 1), 1)
			Next
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RandStr charNumber[:range] | min-max | string[:range]
	'@ 返  回:  经过格式化的字符串
	'@ 作  用:  仅把字符串中的换行符和空格替换为浏览器可以显示的标签，
	'@ 			其它的HTML标签不作处理
	'==DESC=====================================================================================
	'@ charNumber : Integer (整数) 要生成的字符串的长度
	'@ range(可选) : String (字符串) 要生成的字符串的字符范围
	'@ min : Integer (整数) 生成随机数的最小值，必须和max配合使用
	'@ max : Integer (整数) 生成随机数的最大值，必须和min配合使用
	'@ string : String (字符串) 要将随机字符串嵌入的字符串，可以嵌入随机字符串和随机数字：
	'@  - 用"<n>"表示字符串中要加入的随机字符串的位数
	'@  - 用"<min-max>"表示字符串中要加入的随机数字的最大值和最小值
	'==DEMO=====================================================================================
	'@ AB.C.RandStr(12) 12位的随机字符串
	'@ AB.C.RandStr("100000-999999") 6位的随机数
	'@ AB.C.RandStr("8:0123456789abcdefghijklmnopqrstuvwxyz~!@#$%^&*_-+=") 包含特殊字符的8位数密码
	'@ AB.C.RandStr("Random Color \: #<6>:0123456789ABCDEF") 字符串内生成一个随机的16进制颜色代码
	'@ AB.C.RandStr("{<8>-<4>-<4>-<4>-<12>}:0123456789ABCDEF") 生成一个CLSID(类ID)
	'@ AB.C.RandStr("CN-\<86\>-<6>-<10000-99999>") 生成一个自定义的包含固定编码部分的随机编码
	'@ AB.C.RandStr("No.<1-2999>") 生成一个3000以内的编号
	'@ *****************************************************************************************

	Function RandStr(ByVal cfg)
		Dim a, p, l, t, reg, m, mi, ma
		cfg = Replace(Replace(Replace(cfg,"\<",Chr(0)),"\>",Chr(1)),"\:",Chr(2))
		a = ""
		If Test(cfg, "(<\d+>|<\d+-\d+>)") Then
			t = cfg
			p = Abx_Param(cfg)
			If Not isNul(p(1)) Then
				a = p(1) : t = p(0) : p = ""
			End If
			Set reg = RegMatch(cfg, "(<\d+>|<\d+-\d+>)")
			For Each m In reg
				p = m.SubMatches(0)
				l = Mid(p,2,Len(p)-2)
				If Test(l,"^\d+$") Then
					t = Replace(t,p,Rand(l,a),1,1)
				Else
					mi = CLeft(l,"-")
					ma = CRight(l,"-")
					t =  Replace(t,p,Rand(mi, ma),1,1)
				End If
			Next
			Set reg = Nothing
		ElseIf Test(cfg,"^\d+-\d+$") Then
			mi = CLeft(cfg,"-")
			ma = CRight(cfg,"-")
			t = Rand(mi, ma)
		ElseIf Test(cfg, "^(\d+)|(\d+:.)$") Then
			l = cfg : p = Abx_Param(cfg)
			If Not isNul(p(1)) Then
				a = p(1) : l = p(0) : p = ""
			End If
			t = Rand(l, a)
		Else
			t = cfg
		End If
		RandStr = Replace(Replace(Replace(t,Chr(0),"<"),Chr(1),">"),Chr(2),":")
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.ServerVar(s)
	'@ 别  名:  AB.C.RqSv(s)
	'@ 返  回:  Request.ServerVariables(s)的简写
	'@ 作  用:  获取服务器环境变量(获取Request.ServerVariables环境变量集合信息)
	'==PARAM=====================================================================================
	'@ s : String (字符串) 服务器环境变量名
	'==DEMO=====================================================================================
	'@ AB.C.ServerVar("URL") 等同于 Request.ServerVariables("URL")
	'@ *****************************************************************************************

	'Request.ServerVariables()的简写
	Public Function ServerVar(ByVal s)
		ServerVar = Request.ServerVariables(s)
	End Function
	Public Function RqSv(ByVal s)
		RqSv = Request.ServerVariables(s)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.SelfName()
	'@ 返  回:  String
	'@ 作  用:  获取自身文件名
	'==PARAM=====================================================================================
	'@ none
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.SelfName()
	'@ *****************************************************************************************

	Public Function SelfName()
		Dim tmp : tmp = RqSv("PATH_TRANSLATED")
		SelfName = LCase(Mid(tmp, InstrRev(tmp, "\") + 1, Len(tmp)))
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Referer
	'@ 返  回:  即 Request.ServerVariables("HTTP_REFERER")的简写
	'@ 作  用:  获取从哪个页面链接过来的URL
	'==PARAM=====================================================================================
	'@ 无参数
	'==DEMO=====================================================================================
	'@ AB.C.Referer => Request.ServerVariables("HTTP_REFER")
	'@ *****************************************************************************************

	Public Function Referer()
		Referer = Request.ServerVariables("HTTP_REFERER")
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.IsInstall objectName
	'@ 返  回:  Boolean (布尔值)
	'@ 作  用:  检测服务器上是否已经安装了某个组件
	'==DESC=====================================================================================
	'@ objectName : String (字符串) 服务器组件的工程名和类名字符串
	'==DEMO=====================================================================================
	'@ Dim msg
	'@ If AB.C.IsInstall("JMail.Message") Then
	'@     set msg = Server.CreateOBject("JMail.Message")
	'@ Else
	'@     AB.C.Print "未安装Jmail组件"
	'@ End If
	'@ *****************************************************************************************

	Function isInstall(Byval s)
		On Error Resume Next : Err.Clear()
		isInstall = False
		Dim obj : Set obj = Server.CreateObject(s)
		If Err.Number = 0 Then isInstall = True
		Set obj = Nothing : Err.Clear()
		On Error Goto 0
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.DateTime date, format|otherDate
	'@ 返  回:  经过格式化后的日期时间
	'@ 作  用:  此方法可以把一个日期或时间格式化为指定的格式后输出。
	'@ 			format 参数区分大小写，该方法中均采用小写字母，直接重复表示用几位来显示该项，
	'@ 			比如yyyy表示2008，mm则表示01。
	'@ 			如果自定义的格式字符串本身中需要包含以上字符，则需要在前面加上“\”进行转义。
	'@ 			另外如果第二个参数也是一个时间或者为空字符串，
	'@ 			则此方法将把两个时间的差输出为 某某时间之前 或者 某某时间之后 ，
	'@ 			如：“24天前”或“38分钟后”。
	'@ 			如果为空字符串时，则计算时间差的基准时间为现在时间且超过2个星期则直接显示时间。
	'==DESC=====================================================================================
	'@ date Datetime (时间日期) 要格式化的日期时间
	'@ format String (字符串)
	'@ 		可以是0-4的数字，输出系统定义的日期和时间格式，功能同vbScript的FormatDateTime函数。
	'@ 		也可以是一个包含下列字符的时间日期格式字符串(以下均为小写)：
	'@ 		y - 年
	'@ 		m - 月
	'@ 		mmm - 月(英文3位缩写)
	'@ 		mmmm - 月(英文)
	'@ 		d - 日
	'@ 		h - 时
	'@ 		i - 分
	'@ 		s - 秒
	'@ 		w - 星期(中文)
	'@ 		ww - 星期(英文)
	'@ 		www - 星期(英文3位缩写)
	'@ otherDate "" (空字符串) 或 Datetime (时间日期)
	'@ 		格式化为“多久前”或“多久后”的基准时间
	'@ 		如果为空字符串，则基准时间为现在（Now()），
	'@ 		而且时间差超过2个星期则直接显示为日期时间而不是“之前”或“之后”
	'==DEMO=====================================================================================
	'@ AB.C.DateTime(Cdate("2008-9-1 06:00:01"),"yy年mm月dd日h时i分ss秒 星期w, \hello")
	'@ 返回值: 08年09月01日6时0分01秒 星期六, hello
	'@ "上传于" & AB.C.DateTime(Cdate("2008-9-1 06:00:01"),Now())
	'@ 假设现在的时间是2008-12-10, 则返回值: 上传于3个月前
	'@ *****************************************************************************************

	Public Function DateTime(ByVal iTime, ByVal iFormat)
		If isNul(iTime) Then DateTime = "" : Exit Function
		If Not IsDate(iTime) Then DateTime = "Date Error" : Exit Function
		If Instr(",0,1,2,3,4,",","&iFormat&",")>0 Then DateTime = FormatDateTime(iTime,iFormat) : Exit Function
		Dim diffs,diffd,diffw,diffm,diffy,dire,before,pastTime
		Dim iYear, iMonth, iDay, iHour, iMinute, iSecond,iWeek,tWeek
		Dim iiYear, iiMonth, iiDay, iiHour, iiMinute, iiSecond,iiWeek
		Dim iiiWeek, iiiMonth, iiiiMonth
		Dim SpecialText, SpecialTextRe,i,t
		iYear = right(Year(iTime),2) : iMonth = Month(iTime) : iDay = Day(iTime)
		iHour = Hour(iTime) : iMinute = Minute(iTime) : iSecond = Second(iTime)
		iiYear = Year(iTime) : iiMonth = right("0"&Month(iTime),2)
		iiDay = right("0"&Day(iTime),2) : iiHour = right("0"&Hour(iTime),2)
		iiMinute = right("0"&Minute(iTime),2) : iiSecond = right("0"&Second(iTime),2)
		tWeek = Weekday(iTime)-1 : iWeek = Array("日","一","二","三","四","五","六")
		If isDate(iFormat) or isNul(iFormat) Then
			If isNul(iFormat) Then : iFormat = Now() : pastTime = true : End If
			dire = "后" : If DateDiff("s",iFormat,iTime)<0 Then : dire = "前" : before = True : End If
			diffs = Abs(DateDiff("s",iFormat,iTime))
			diffd = Abs(DateDiff("d",iFormat,iTime))
			diffw = Abs(DateDiff("ww",iFormat,iTime))
			diffm = Abs(DateDiff("m",iFormat,iTime))
			diffy = Abs(DateDiff("yyyy",iFormat,iTime))
			If diffs < 60 Then DateTime = "刚刚" : Exit Function
			If diffs < 1800 Then DateTime = Int(diffs\60) & "分钟" & dire : Exit Function
			If diffs < 2400 Then DateTime = "半小时"  & dire : Exit Function
			If diffs < 3600 Then DateTime = Int(diffs\60) & "分钟" & dire : Exit Function
			If diffs < 259200 Then
				If diffd = 3 Then DateTime = "3天" & dire & " " & iiHour & ":" & iiMinute : Exit Function
				If diffd = 2 Then DateTime = IIF(before,"前天 ","后天 ") & iiHour & ":" & iiMinute : Exit Function
				If diffd = 1 Then DateTime = IIF(before,"昨天 ","明天 ") & iiHour & ":" & iiMinute : Exit Function
				DateTime = Int(diffs\3600) & "小时" & dire : Exit Function
			End If
			If diffd < 7 Then DateTime = diffd & "天" & dire & " " & iiHour & ":" & iiMinute : Exit Function
			If diffd < 14 Then
				If diffw = 1 Then DateTime = IIF(before,"上星期","下星期") & iWeek(tWeek) & " " & iiHour & ":" & iiMinute : Exit Function
				If Not pastTime Then DateTime = diffd & "天" & dire : Exit Function
			End If
			If Not pastTime Then
				If diffd < 31 Then
					If diffm = 2 Then DateTime = "2个月" & dire : Exit Function
					If diffm = 1 Then DateTime = IIF(before,"上个月","下个月") & iDay & "日" : Exit Function
					DateTime = diffw & "星期" & dire : Exit Function
				End If
				If diffm < 36 Then
					If diffy = 3 Then DateTime = "3年" & dire : Exit Function
					If diffy = 2 Then DateTime = IIF(before,"前年","后年") & iMonth & "月" : Exit Function
					If diffy = 1 Then DateTime = IIF(before,"去年","明年") & iMonth & "月" : Exit Function
					DateTime = diffm & "个月" & dire : Exit Function
				End If
				DateTime = diffy & "年" & dire : Exit Function
			Else
				iFormat = "yyyy-mm-dd hh:ii"
			End If
		End If
		iiWeek = Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")
		iiiWeek = Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat")
		iiiMonth = Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
		iiiiMonth = Array("January","February","March","April","May","June","July","August","September","October","November","December")
		SpecialText = Array("y","m","d","h","i","s","w")
		SpecialTextRe = Array(Chr(0),Chr(1),Chr(2),Chr(3),Chr(4),Chr(5),Chr(6))
		For i = 0 To 6 : iFormat = Replace(iFormat,"\"&SpecialText(i), SpecialTextRe(i)) : Next
		t = Replace(iFormat,"yyyy", iiYear) : t = Replace(t, "yyy", iiYear)
		t = Replace(t, "yy", iYear) : t = Replace(t, "y", iiYear)
		t = Replace(t, "mmmm", Replace(iiiiMonth(iMonth-1),"m",Chr(1))) : t = Replace(t, "mmm", iiiMonth(iMonth-1))
		t = Replace(t, "mm", iiMonth) : t = Replace(t, "m", iMonth)
		t = Replace(t, "dd", iiDay) : t = Replace(t, "d", iDay)
		t = Replace(t, "hh", iiHour) : t = Replace(t, "h", iHour)
		t = Replace(t, "ii", iiMinute) : t = Replace(t, "i", iMinute)
		t = Replace(t, "ss", iiSecond) : t = Replace(t, "s", iSecond)
		t = Replace(t, "www", iiiWeek(tWeek)) : t = Replace(t, "ww", iiWeek(tWeek))
		t = Replace(t, "w", iWeek(tWeek))
		For i = 0 To 6 : t = Replace(t, SpecialTextRe(i),SpecialText(i)) : Next
		DateTime = t
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Format stirng, obj
	'@ 返  回:  经过字符替换后的字符串
	'@ 作  用:  可以把各种带有集合特征的对象按字符串内占位符的形式把值替换到字符串中，
	'@ 			能够很方便的用于各种字符串内变量的拼接。
	'@ 			同时可在占位符中对要替换的值进行一些简单的格式化操作。
	'@ 			与 AB.C.Str 方法不同的是，此方法内字符串占位符的下标由0开始。
	'==DESC=====================================================================================
	'@ stirng : String (字符串)
	'@   包含占位符的字符串，占位符用{}符号包含，视参数的不同，占位符中间可以是数字或者名称。
	'@   如果占位符是数字，则编号从0开始表示第一个元素。
	'@   如果字符串中本身就包含 { 字符，则需要用 \{ 进行转义。
	'@ obj : Array (数组) 或 Object (ASP对象) 或 Recordset (记录集对象) 或 String (字符串)
	'@  用于格式化占位符的数据源，可以是以下类型：
	'@    字符串 - 只替换 {0} 占位符；
	'@    数组 - 依次替换占位符中的 {数字} 为对应的数组元素；
	'@    记录集(Recordset) - 依次替换占位符中的 {数字} 或 {列名} 为本条记录的相应值；
	'@    字典(Dictinary) - 依次替换占位符中的 {键名} 为字典中对应的值；
	'@    Match集合 - 替换 {0} 为匹配本身，然后从 {1} 开始替换占位符中的数字为对应的子集合(SubMatches)的值；
	'@    SubMatches集合 - 依次替换占位符中的 {数字} 为本条集合中对应的值；
	'@    AspBox List对象 - 依次替换占位符中的 {数字} 或 {Hash列名} 为数组中对应的值。
	'==DEMO=====================================================================================
	'@ '字符串参数
	'@   AB.C.Print AB.C.Format("This is a {0}.", "Text")
	'@ '输出：This is a Text
	'@
	'@ '数组参数
	'@   AB.C.Print AB.C.Format("name:{0}/sex:{1}/age:{2}", Array("Ertan", "Male", 38))
	'@ '输出：name:Ertan/sex:Male/age:38
	'@
	'@ '格式化记录集值
	'@ Dim rs
	'@ Set rs = AB.db.GR("Users:ID,Name,QQ,Mail","","")
	'@ While Not rs.EOF
	'@   '格式化记录集时，占位符可用数字和列名
	'@   AB.C.Print AB.C.Format("{0} / {1} / {qq} / {mail}",rs)
	'@   '输出： 10 / AlexFu / 8000121 / alex@alexfu.com
	'@   rs.MoveNext
	'@ Wend
	'@ AB.db.C(rs)
	'@
	'@ '格式化Dictionary值
	'@ Dim d
	'@ Set d = CreateObject(AB.DictName)
	'@ d.Add "a","Athens"
	'@ d.Add "b","Belgrade"
	'@ d.Add "c","Cairo"
	'@ '格式化字典对象时只能用列名
	'@   AB.C.Print AB.C.Format("{a}/{c}",d)
	'@ '输出： Athens/Cairo
	'@ Set d = Nothing
	'@
	'@ '格式化List对象
	'@ Dim list
	'@ Set list = AB.List.New
	'@ list.Hash = "name:Scott pwd:tiger age:39 job:CFO"
	'@ '格式化list对象时，可以用数字，如果是Hash还可以用列名
	'@   AB.C.Print AB.C.Format("{0} / {pwd} / {2} / {job}", list)
	'@ '输出： Scott / tiger / 39 / CFO
	'@ Set list = Nothing
	'@
	'@ '格式化Match对象
	'@ Dim s,m,match
	'@ s = "<em>Scott/Tiger</em><em>Smith/Cat</em>"
	'@ Set m = AB.C.RegMatch(s, "<em>(\w+)/(\w+)</em>")
	'@ For Each match In m
	'@   AB.C.Print AB.C.Format("{0} | {1}", match.SubMatches)
	'@   '输出： Scott | Tiger
	'@ Next
	'@ For Each match In m
	'@ '如果直接用match作为参数，则第1个元素为match本身的值
	'@   AB.C.Print AB.C.Format("{0} &gt; {1} | {2}", match)
	'@   '输出： <em>Scott/Tiger</em> &gt; Scott | Tiger
	'@ Next
	'@ Set m = Nothing
	'@
	'@ '在占位符中使用参数格式化
	'@ Dim a
	'@ a = Array(.3453,2372291.876,-34.28,Now,"I'm Lajox")
	'@ '参数N表示格式化数字，语法为 "N[,或%或(][数字]"，后面两项均为可选:
	'@ '("," - 用千位分隔符；"%" - 转换为百分比；"(" - 负数用括号包含；数字 - 小数位数)
	'@   AB.C.Print AB.C.Format("{0:N} / {0:N3} / {0:N%2} / {1:N,} / {2:N(1}",a)
	'@ '输出：0.3453 / 0.345 / 34.53% / 2,372,291.88 / (34.3)
	'@
	'@ '参数D表示格式化日期，用法和AB.C.DateTime一样
	'@ '参数U表示转化为大写字母，参数L表示转化为小写字母
	'@   AB.C.Print AB.C.Format("{3:Dy-mm-dd} / {4:U} / {4:L}",a)
	'@ '输出：2010-08-18/I'M Lajox/i'm lajox
	'@
	'@ '参数E表示使用ASP语句表达式，用%s代替值在语句中的位置，AB.C的方法可省略 AB.C. 前缀
	'@   AB.C.Print AB.C.Format("{4:ECLeft(%s,"" "")} / {3:EDateTime(%s,""星期w"")}",a)
	'@ '输出：I'm / 星期三
	'@ *****************************************************************************************

	Public Function Format(ByVal s, ByVal v)
		Format = FormatString(s, v, 0)
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.GetUrl type|[:]hash
	'@ 返  回:  经过处理的页面Url值 # [String]
	'@ 作  用:  获取并处理当前文件的地址
	'==Param==============================================================
	'@ type "" (空字符串) 或 Integer (整数)
	'@   参数为空字符串时返回本页面绝对地址并带有页面Hash参数
	'@   参数为0时返回本页面相对地址，且不带页面Hash参数
	'@   参数为1时返回本页面相对地址，带页面Hash参数
	'@   参数为2时返回本页面所在目录相对地址
	'@ :(可选) String (字符串)
	'@   字符串中的冒号，不省略此参数时将在返回的URI地址中过滤掉当前文件名
	'@ hash String (字符串)
 	'@   用,(逗号)隔开的Hash参数名，当名称前添加-(减号)时表示从URI中过滤掉此参数，不加则表示只返回这些Hash参数
	'@ 调用此方法将返回本页页面的地址，该方法有一个参数，但根据该参数的不同可以返回多种不同的结果。
	'@ 可以用字符串列表参数返回只带该参数名称的Hash值的Url地址，
	'@ 也可以用带-号的字符串列表参数返回带除了这些参数名称的Hash值之外的所有Hash参数的Url地址。
	'@ 下面的例子将说明此方法的调用:
	'@ 比如本页面的实际地址为: http://www.ambox.cn:8080/news/index.asp?type=public&feed=on&page=23
	'@ 方法                         返回结果
	'@   AB.C.GetUrl("")             以上url的全部内容
	'@   AB.C.GetUrl(-1)             http://www.ambox.cn:8080
	'@   AB.C.GetUrl(0)              /news/index.asp
	'@   AB.C.GetUrl(1)              /news/index.asp?type=public&feed=on&page=23
	'@   AB.C.GetUrl(2)              /news/
	'@   AB.C.GetUrl(3)              http://www.ambox.cn:8080/news/index.asp
	'@   AB.C.GetUrl(4)              index.asp?type=public&feed=on&page=23
	'@   AB.C.GetUrl(5)              index.asp
	'@   AB.C.GetUrl(6)              ?type=public&feed=on&page=23
	'@   AB.C.GetUrl("page")         /news/index.asp?page=23
	'@   AB.C.GetUrl("-page")        /news/index.asp?type=public&feed=on
	'@   AB.C.GetUrl(":")            /news/?type=public&feed=on&page=23
	'@   AB.C.GetUrl(":-feed,-page") /news/?type=public
	'==DEMO==============================================================
	'@ 举例: 地址/product/edit/index.asp?action=save&page=3
	'@ AB.C.RR(AB.C.GetUrl(":-action")) 将跳转到 /product/edit/?page=3
	'@ ******************************************************************

	Public Function GetUrl(ByVal param)
		Dim script_name,url,dir,self
		Dim out,qitem,qtemp,i,hasQS,qstring
		param = param & ""
		script_name = ServerVar("SCRIPT_NAME")
		url = script_name
		dir  = Left(script_name,InstrRev(script_name,"/"))
		self  = Mid(script_name, InstrRev(script_name,"/")+1, Len(script_name))
		Dim ustart,uport,host
		If ServerVar("HTTPS")="on" Then
			ustart = "https://"
			uport = IIF(Int(ServerVar("SERVER_PORT"))=443,"",":"&ServerVar("SERVER_PORT"))
		Else
			ustart = "http://"
			uport = IIF(Int(ServerVar("SERVER_PORT"))=80,"",":"&ServerVar("SERVER_PORT"))
		End If
		host = ustart & ServerVar("SERVER_NAME") & uport
		If isNul(param) or param = "-1" Then
			If isNul(param) Then
				url = host & script_name
			Else
				GetUrl = host : Exit Function
			End If
			If Has(s_rq) Then url = url & "?" & s_rq
			GetUrl = url : Exit Function
		End If
		If param = "0" Then : GetUrl = url : Exit Function
		If param = "2" Then : GetUrl = dir : Exit Function
		If param = "3" Then : GetUrl = host & script_name : Exit Function
		If param = "4" Then : GetUrl = self & IIF(Has(s_rq), "?"&s_rq, "") : Exit Function
		If param = "5" Then : GetUrl = self : Exit Function
		If param = "6" Then : GetUrl = IIF(Has(s_rq), "?"&s_rq, "") : Exit Function
		If InStr(param,":")>0 Then
			url = dir
			out = Mid(param,2)
			hasQS = IIF(isNul(out),0,1)
		Else
			out = param : hasQS = 1
		End If
		If Has(s_rq) Then
			If param="1" Or hasQS = 0 Then
				url = url & "?" & s_rq
			Else
				qtemp = "" : i = 0 : out = ","&out&","
				qstring = IIF(InStr(out,"-")>0,"Not InStr(out,"",-""&qitem&"","")>0","InStr(out,"",""&qitem&"","")>0")
				For Each qitem In Request.QueryString()
					If Eval(qstring) Then
						If i<>0 Then qtemp = qtemp & "&"
						qtemp = qtemp & qitem & "=" & Request.QueryString(qitem)
						i = i + 1
					End If
				Next
				If Has(qtemp) Then url = url & "?" & qtemp
			End If
		End If
		GetUrl = url
	End Function

	'@ ******************************************************************
	'@ 过程名:  AB.C.GetUrlWith [page:|:]type, newParam
	'@ 返  回:  经过处理的页面Url值 # [String]
	'@ 作  用:  获取当前页面的URL地址并加上新参数
	'==Param==============================================================
	'@ page(可选) String (字符串)
	'@   要转向的新页面地址
	'@ :(可选) String (字符串)
	'@   字符串中的冒号，不省略此参数时将在返回的URI地址中过滤掉当前文件名
	'@ type "" (空字符串) 或 Integer (整数)
	'@   参数为空字符串时返回本页面绝对地址并带有页面Hash参数
	'@   参数为0时返回本页面相对地址，且不带页面Hash参数
	'@   参数为1时返回本页面相对地址，带页面Hash参数
	'@   参数为2时返回本页面所在目录相对地址
	'@ newParam String (字符串)
	'@   新Url参数，用Hash字符串的格式如(a=1&b=2&c=no)
	'@
	'@ 返回本页页面的地址并在原地址后面加上新的Url参数，type 参数的用法同AB.C.GetUrl方法的参数用法完全一样。
	'@ 如果不省略 page 参数，将会返回 page 参数指定的页面地址并带上新的URL参数。

	'@ 比如本页面的实际地址为: http://www.ambox.com/public/news/index.asp?type=public&feed=on&page=23
	'@  AB.C.Print AB.C.GetUrlWith("-feed,-page","page=4&feed=off")
	'@  '输出 /public/news/index.asp?type=public&page=4&feed=off
	'@  AB.C.Print AB.C.GetUrlWith("/public/list.asp:-feed,-page","page=4&feed=off")
	'@  '输出 /public/list.asp?type=public&page=4&feed=off
	'==DEMO==============================================================
	'@ 举例: 地址/product/edit/index.asp?action=save&page=3
	'@ AB.C.RR(AB.C.GetUrlWith("list.asp:-action","info=保存成功"))
	'@ 将跳转到：/product/edit/list.asp?page=3&info=保存成功
	'@ ******************************************************************

	Public Function GetUrlWith(ByVal p, ByVal v)
		Dim u,s,n
		s = IIF(p=-1,GetUrl(-1)&"/","")
		s = IIF(isNul(p),GetUrl(""),GetUrl(0))
		If Instr(p,":")>0 Then
			If Has(CLeft(p,":")) Then
				n = Cleft(p,":") : p = CRight(p,":")
			End If
		End If
		u = GetUrl(p)
		If Left(p,1)=":" Then s = Left(u,InstrRev(u,"/"))
		u = u & IfThen(Has(v),IIF(isNul(Mid(u,len(s)+1)),"?","&") & v)
		If Has(n) Then
			If Instr(u,"?")>0 Then
				u = n & Mid(u,Instr(u,"?"))
			Else
				u = n
			End If
		End If
		GetUrlWith = u
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetIp()
	'@ 返  回:  IP地址
	'@ 作  用:  获取到的IP地址，如果无法获取则返回0.0.0.0
	'==DESC=====================================================================================
	'@ 无
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function GetIP()
		Dim addr, x, y
		x = ServerVar("HTTP_X_FORWARDED_FOR")
		y = ServerVar("REMOTE_ADDR")
		addr = IIF(isNul(x) or LCase(x)="unknown",y,x)
		If InStr(addr,".")=0 Then addr = "0.0.0.0"
		If InStr(addr,":")>0 Then addr = "127.0.0.1"
		GetIP = addr
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.getOS()
	'@ 返  回:  操作系统信息
	'@ 作  用:  获取操作系统信息（电脑系统、手机系统、蜘蛛）
	'==DESC=====================================================================================
	'@ 无
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function getOS()
		dim vOS, UserAgent
		UserAgent = Request.ServerVariables("HTTP_USER_AGENT")
		'--先判定手机系统
		if instr(1,UserAgent,"Windows CE",1)>0 then
			vOs="Windows CE|手机系统"
		elseif instr(1,UserAgent,"iPhone",1)>0 then
			vOs="iPhone|手机系统"
		elseif instr(1,UserAgent,"BlackBerry",1)>0 then
			vOs="BlackBerry|手机系统"
		elseif instr(1,UserAgent,"Series60",1)>0 and instr(1,UserAgent,"NOKIA",1)>0 then
			vOs="Nokia S60|手机系统"
		elseif instr(1,UserAgent,"NOKIA",1)>0 then
			vOs="Nokia|手机系统"
		elseif instr(1,UserAgent,"SymbianOS",1)>0 or instr(1,UserAgent,"Series",1)>0 then
			vOs="SymbianOS|手机系统"
		elseif instr(1,UserAgent,"SonyEricsson",1)>0 then
			vOs="SonyEricsson|手机系统"
		elseif instr(1,UserAgent,"LG",1)>0 then
			vOs="LG手机|手机系统"
		elseif instr(1,UserAgent,"MOT",1)>0 or instr(1,UserAgent,"Motorola",1)>0 then
			vOs="MOTO手机|手机系统"
		elseif instr(1,UserAgent,"SEC",1)>0 or instr(1,UserAgent,"SAMSUNG",1)>0 then
			vOs="三星手机|手机系统"
		elseif instr(1,UserAgent,"ZTE")>0 then
			vOs="中兴手机|手机系统"
		elseif instr(1,UserAgent,"DX",1)>0 or instr(1,UserAgent,"DAXIAN",1)>0 then
			vOs="大显手机|手机系统"
		elseif instr(1,UserAgent,"TELSON",1)>0 then
			vOs="泰信[代工]手机|手机系统"
		elseif instr(1,UserAgent,"Dopod",1)>0 then
			vOs="多普达手机|手机系统"
		elseif instr(1,UserAgent,"PHILIPS",1)>0 then
			vOs="PHILIPS手机|手机系统"
		elseif instr(1,UserAgent,"Haier",1)>0 then
			vOs="海尔手机|手机系统"
		elseif instr(1,UserAgent,"LENOVO",1)>0 then
			vOs="联想手机|手机系统"
		elseif instr(1,UserAgent,"CECT",1)>0 then
			vOs="CECT手机|手机系统"
		elseif instr(1,UserAgent,"NEC",1)>0 then
			vOs="NEC手机|手机系统"
		elseif instr(1,UserAgent,"Bird",1)>0 then
			vOs="波导手机|手机系统"
		elseif instr(1,UserAgent,"DBTEL",1)>0 then
			vOs="迪比特手机|手机系统"
		elseif instr(1,UserAgent,"TCL",1)>0 then
			vOs="TCL手机|手机系统"
		elseif instr(1,UserAgent,"oppo",1)>0 then
			vOs="Oppo手机|手机系统"
		elseif instr(1,UserAgent,"AMOI",1)>0 then
			vOs="夏新手机|手机系统"
		elseif instr(1,UserAgent,"Alcatel",1)>0 then
			vOs="阿尔卡特手机|手机系统"
		elseif instr(1,UserAgent,"Ericsson",1)>0 then
			vOs="爱立信手机|手机系统"
		elseif instr(1,UserAgent,"BenQ",1)>0 then
			vOs="明基手机|手机系统"
		elseif instr(1,UserAgent,"KONKA",1)>0 then
			vOs="康佳手机|手机系统"
		elseif instr(1,UserAgent,"ChangHong",1)>0 then
			vOs="长虹手机|手机系统"
		elseif instr(1,UserAgent,"MALATA",1)>0 then
			vOs="万利达手机|手机系统"
		elseif instr(1,UserAgent,"KTOUCH",1)>0 or instr(1,UserAgent,"TIANYU",1)>0 or instr(1,UserAgent,"K-TOUCH",1)>0 then
			vOs="天语手机|手机系统"
		'--下面2个要在手机中最后判定,最普通的手机了MAUI
		elseif instr(1,UserAgent,"MAUI",1)>0 then
			vOs="MTK杂牌手机|手机系统"
		elseif instr(1,UserAgent,"MIDP",1)>0 or instr(1,UserAgent,"JAVA",1)>0 or instr(1,UserAgent,"J2ME",1)>0 then
			vOs="Java移动设备|手机系统"
		else
			vOs="Other|手机系统"
		end if
		if vOs<>"Other|手机系统" then:getOS=vOS:exit Function:end if
		'---再判定电脑系统
		if instr(1,UserAgent,"Windows NT 6.1",1)>0 then
			vOS="Windows 7|电脑系统"
		elseif instr(1,UserAgent,"Windows NT 6.0",1)>0 then
			vOS="Windows Vista|电脑系统"
		elseif instr(1,UserAgent,"Windows NT 5.2",1)>0 then
			vOS="Windows 2003|电脑系统"
		elseif instr(1,UserAgent,"Windows NT 5.1",1)>0 then
			vOs="Windows XP|电脑系统"
		elseif instr(1,UserAgent,"Windows NT 5.0",1)>0 then
			vOS="Windows 2000|电脑系统"
		elseif instr(1,UserAgent,"Windows NT",1)>0 then
			vOs="Windows NT|电脑系统"
		'--4.0 is win95 ,4.1 is win98 ,4.9 is win me
		elseif instr(1,UserAgent,"Windows 9",1)>0 or instr(1,UserAgent,"Windows 4",1)>0 then
			vOs="Windows 9x|电脑系统"
		elseif instr(1,UserAgent,"Unix",1)>0 or instr(1,UserAgent,"SunOS",1)>0 or instr(1,UserAgent,"BSD",1)>0 then
			vOs="Unix|电脑系统"
		elseif instr(1,UserAgent,"RedHat",1)>0 then
			vOs="Linux RedHat|电脑系统"
		elseif instr(1,UserAgent,"Ubuntu",1)>0 then
			vOs="Linux Ubuntu|电脑系统"
		elseif instr(1,UserAgent,"Linux",1)>0 then
			vOs="Linux|电脑系统"
		elseif instr(1,UserAgent,"Mac",1)>0 then
			vOs="Mac|电脑系统"
		else
			vOs="Other|电脑系统"
		end if
		if vOs<>"Other|电脑系统" then:getOS=vOS:exit Function:end if '以上判定电脑系统完完毕
		'-------最后判定搜索蜘蛛 '蜘蛛spider
		if instr(1,UserAgent,"Baiduspider",1)>0 then
			vOs="Baidu spider|搜索蜘蛛"
		elseif instr(1,UserAgent,"Googlebot",1)>0 then
			vOs="Google bot|搜索蜘蛛"
		elseif instr(1,UserAgent,"msnbot",1)>0 then
			vOs="Msn bot|搜索蜘蛛"
		elseif instr(1,UserAgent,"Yahoo",1)>0 then
			vOs="Yahoo bot|搜索蜘蛛"
		elseif instr(1,UserAgent,"Sogou",1)>0 then
			vOs="Sogou spider|搜索蜘蛛"
		elseif instr(1,UserAgent,"YodaoBot",1)>0 then
			vOs="Yodao Bot|搜索蜘蛛"
		elseif instr(1,UserAgent,"Sosospider",1)>0 then
			vOs="Soso spider|搜索蜘蛛"
		else
		   vOs="Other|搜索蜘蛛"
		end if
		if vOs="Other|搜索蜘蛛" then:vOs="Other|Other":getOS=vOS:exit Function:end if
		getOS=vOS
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.getBS()
	'@ 返  回:  获取浏览器信息
	'@ 作  用:  获取浏览器信息（电脑系统浏览器、手机浏览器）
	'==DESC=====================================================================================
	'@ 无
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function getBS()
		dim vOS, UserAgent
		UserAgent = Request.ServerVariables("HTTP_USER_AGENT")
		if UserAgent="UserAgent Unknown" then :vOs="UserAgent isNull Browser Unknown|Other":getBS=vOS:exit Function:end if
		'--先判定使用IE内核的浏览器：MAXTHON，GreenBrowser，TencentTraveler，MyIE，NetCaptor
		if instr(1,UserAgent,"GreenBrowser",1)>0 then
			vOS="GreenBrowser|浏览器"
		elseif instr(1,UserAgent,"NetCaptor",1)>0 then
			vOS="NetCaptor|浏览器"
		elseif instr(1,UserAgent,"TencentTraveler",1)>0 then
			vOS="TencentTraveler|浏览器"
		elseif instr(1,UserAgent,"TheWorld",1)>0 then
			vOS="TheWorld|浏览器"
		elseif instr(1,UserAgent,"MAXTHON",1)>0 then
			vOS="Maxthon|浏览器"
		elseif instr(1,UserAgent,"MyIE",1)>0 then
			vOS="MyIE|浏览器"
		elseif instr(1,UserAgent,"360SE",1)>0 then
			vOS="360IE|浏览器"
		elseif instr(1,UserAgent,"360chrome",1)>0 then
			vOS="360Chrome|浏览器"
		'--用IE内核的浏览器的判定要在IE前进行
		elseif instr(1,UserAgent,"Trident",1)>0 AND instr(1,UserAgent,"rv:11.0",1)>0 then
			vOS="IE 11|浏览器"
		elseif instr(1,UserAgent,"MSIE 10",1)>0 then
			vOS="IE 10|浏览器"
		elseif instr(1,UserAgent,"MSIE 9",1)>0 then
			vOS="IE 9|浏览器"
		elseif instr(1,UserAgent,"MSIE 8",1)>0 then
			vOS="IE 8|浏览器"
		elseif instr(1,UserAgent,"MSIE 7",1)>0 then
			vOS="IE 7|浏览器"
		elseif instr(1,UserAgent,"MSIE 6",1)>0 then
			vOS="IE 6|浏览器"
		elseif instr(1,UserAgent,"MSIE 5.5",1)>0 then
			vOS="IE 5.5|浏览器"
		elseif instr(1,UserAgent,"MSIE 5",1)>0 then
		   vOS="IE 5|浏览器"
		elseif instr(1,UserAgent,"MSIE 4",1)>0 then
			vOS="IE 4|浏览器"
		elseif instr(1,UserAgent,"MSIE 3",1)>0 then
			vOS="IE 3|浏览器"
		'--下面是非IE内核浏览器
		elseif instr(1,UserAgent,"Netscape",1)>0 then
			vOS="Netscape|浏览器"
		elseif instr(1,UserAgent,"Chrome",1)>0 then
			vOS="Chrome|浏览器"
		elseif instr(1,UserAgent,"Firefox",1)>0 then
			vOS="Firefox|浏览器"
		elseif instr(1,UserAgent,"Safari",1)>0 then
			vOS="Safari|浏览器"
		elseif instr(1,UserAgent,"Opera Mini",1)>0 then
			vOS="Opera Mini|浏览器"
		elseif instr(1,UserAgent,"Opera",1)>0 or instr(1,UserAgent,"Presto",1)>0 then
			vOS="Opera|浏览器"
		elseif instr(1,UserAgent,"R4EA",1)>0 then
			vOS="R4EA|浏览器"
		elseif instr(1,UserAgent,"UP",1)>0 then
			vOS="UP|浏览器"
		elseif instr(1,UserAgent,"UCWEB",1)>0 then
			vOS="UCWEB|浏览器"
		else
			vOS="Other|浏览器"
		end if
		getBS=vOS
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.RewriteRule rule, url
	'@ 返  回:  无返回值
	'@ 作  用:  用标准模式设置AspBox的URL伪静态规则
	'@ 			语法类似于其它的URL重写组件（如ISAPI Rewrite）的规则，
	'@ 			用 url 参数中的 $1/$2 等引用 rule 正则中的编组。
	'==DESC=====================================================================================
	'@ rule : String (字符串) 包含重写规则的正则表达式，重写规则必须以根路径开始
	'@ url : String (字符串) 包含参数信息的url字符串，必须以 / 开头
	'==DEMO=====================================================================================
	'@ '设置重写规则
	'@ AB.C.RewriteRule "/list/index\.asp\?(\w+)(-(\d+))?\.html", "/list/?type=$1&page=$3"
	'@ AB.C.Print "type: " & AB.C.Get("type:s")
	'@ AB.C.Print "page: " & AB.C.Get("page:n")
	'@
	'@ 设置URL地址如： http://www.test.com/list/?photo-3.html
	'@ 效果等同于： http://www.test.com/list/?type=photo&page=3
	'@ 上面结果也将是： type: photo page: 3
	'@ *****************************************************************************************

	Public Sub RewriteRule(ByVal s, ByVal u)
		If (Left(s,3)<>"^\/" And Left(s,2)<>"\/" And Left(s,2)<>"^/" And Left(s,1)<>"/") Or Left(u,1)<>"/" Then Exit Sub
		o_rwt.Add ("rule" & i_rule), Array(s,u)
		i_rule = i_rule + 1
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Rewrite urlpage, rule, urlparam
	'@ 返  回:  无返回值
	'@ 作  用:  用高级模式设置EasyASP的URL伪静态规则
	'@ 			专用URL重写方法，由于ASP的限制，AspBox的伪静态是基于 url 参数的，
	'@ 			这个方法更专注于书写伪静态的重写规则，
	'@ 			rule 和 urlparam 是单纯的URL参数对应关系，不再包含复杂的路径信息。
	'==DESC=====================================================================================
	'@ urlpage : "" (空字符串) 或 String (字符串)
	'@ 单个文件路径或用 | 隔开的多个文件路径，每个文件都必须以 / 开头。如果此参数留空，则表示当前文件。
	'@ rule : String (字符串) 包含重写规则的正则表达式，不能包含路径信息
	'@ urlparam : String (字符串) url参数哈希字符串
	'==DEMO=====================================================================================
	'@ 设置重写规则
	'@ AB.C.Rewrite "/list/index.asp", "(\w+)(-(\d+))?\.html", "type=$1&page=$3"
	'@ 如果是设置当前页面，则可以将第1个参数留空，如：
	'@ AB.C.Rewrite "", "(\w+)(-(\d+))?\.html", "type=$1&page=$3"
	'@ AB.C.Print "type: " & AB.C.Get("type:s")
	'@ AB.C.Print "page: " & AB.C.Get("page:n")
	'@
	'@ 设置URL地址如： http://www.test.com/list/?photo-3.html
	'@ 效果等同于： http://www.test.com/list/?type=photo&page=3
	'@ 上面结果也将是： type: photo page: 3
	'@ *****************************************************************************************

	Public Sub Rewrite(ByVal p, ByVal s, Byval u)
		Dim rp,arr,i,rs,ru
		If Left(s,1) = "^" Then s = Mid(s,2)
		If Right(s,1) = "$" Then s = Left(s,Len(s)-1)
		If isNul(p) Then p = GetUrl(0)
		arr = Split(p,"|")
		For i = 0 To Ubound(arr)
			rp = RegEncode(arr(i))
			rs = "^" & rp & "\?" & s & "$"
			ru = arr(i) & "?" & u
			RewriteRule rs, ru
			rp = ""
		Next
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.isRewrite()
	'@ 返  回:  如果当前url地址为已经生效的伪静态地址，返回 True，否则返回 False
	'@ 作  用:  此方法将返回当前访问的地址是否是已经生效的Url重写后的地址
	'==DESC=====================================================================================
	'@ 无参数
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Public Function isRewrite()
		Dim rule,i
		isRewrite = False
		If i_rule = 1 Then Exit Function
		If Has(o_rwt) Then
			s_url = GetUrl(1)
			For Each i In o_rwt
				rule = o_rwt(i)(0)
				If Test(s_url,rule) Then
					isRewrite = True
					s_rwtS = rule
					s_rwtU = CRight(o_rwt(i)(1),"?")
					Exit For
				End If
			Next
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Req name[:type[separator]][:default]
	'@ 返  回:  如果有分隔符，则返回数组；如果没有分隔符，则返回经过处理的字符串。
	'@ 			返回值会根据不同的 type 参数值会进行不同的处理
	'@ 作  用:  安全获取Request值
	'==DESC=====================================================================================
	'@ 参数用法同 AB.C.Get 方法，区别在于：从整个Request中获取
	'==DEMO=====================================================================================
	'@ 参阅 AB.C.Get 方法
	'@ *****************************************************************************************

	Public Function Req(Byval s)
		Dim tmp, i, arrQs, t, hasQ : hasQ = False
		If Instr(s,":")>0 Then
			t = CRight(s,":") : s = CLeft(s,":")
		End If
		For Each i In Request.QueryString
			If i = Trim(s) Then
				hasQ = True
				Exit For
			End If
		Next
		If hasQ Then
			If isRewrite Then
				arrQs = Split(s_rwtU,"&")
				For i = 0 To Ubound(arrQs)
					If s = CLeft(arrQs(i),"=") Then
						tmp = RegReplace(s_url,s_rwtS,CRight(arrQs(i),"="))
						Exit For
					End If
				Next
			Else
				tmp = Request.QueryString(s)
			End If
		Else
			'tmp = Request(s)
			AB.Use "Form"
			If AB.Form.Has(s) Then
				tmp = AB.Form.FormVar(s)
			Else
				tmp = Request(s)
			End If
		End If
		Req = Safe(tmp,t)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Get name[:type[separator]][:default]
	'@ 返  回:  如果有分隔符，则返回数组；如果没有分隔符，则返回经过处理的字符串。
	'@ 			返回值会根据不同的 type 参数值会进行不同的处理
	'@ 作  用:  安全获取QueryString值，支持伪静态页面参数的获取
	'==DESC=====================================================================================
	'@ name String (字符串)
	'@     要获取的参数名，如省略其它参数则相当于原始的Request.QueryString
	'@ type(可选) String (字符串)
	'@   可以是以下字符串：
	'@    "s"  - 表示name是字符串类型的值，会自动处理其中的单引号(')为双单引号('')
	'@    "n"  - 表示name是数值型的值，会验证是否为数值
	'@    "d"  - 表示name是日期型的值，会验证是否为日期
	'@    "na" - 表示name是数值型的值，如果name验证不是数字，则会弹出alert警告框并返回前页
	'@    "da" - 表示name是日期型的值，如果name验证不是日期，则会弹出alert警告框并返回前页
	'@    "ne" - 表示name是数值型的值，如果name验证不是数字，则抛出用户错误信息
	'@    "de" - 表示name是日期型的值，如果name验证不是日期，则抛出用户错误信息
	'@ separator(可选) String (字符串)
	'@   name是由此字符串(特殊符号)隔开的序列，如不省略则会逐个检查name串中的值，并返回一个数组
	'@ default(可选) String (字符串)
	'@   如果name为空或按type检查不符合数值/日期要求，则赋给此默认值；序列则逐个赋值
	'@
	'@ 此方法可以返回一个经过处理的安全的Request.QueryString值，可以用于拼接SQL字符串而不会产生注入问题。
	'@ 如果你想到得到未经处理的原始值，不带任何参数就可以了。
	'==DEMO=====================================================================================
	'@ AB.C.Get("username") 等同 Request.QueryString("username")
	'@ 假设URL: /get.asp?name=Icecream's&birth=1983-9-23&fav=1,a,6,11
	'@ AB.C.Get("name") '返回 Icecream's
	'@ AB.C.Get("name:s") '返回 Icecream''s
	'@ AB.C.Get("birth:d") '返回 1983-9-23
	'@ AB.C.Get("usertype:n:1")'返回 1，因为该参数不存在，这里返回默认值1
	'@ AB.C.Get("fav:n,:0") '返回数组 Array(1,0,6,11), a不是数字，返回默认值0
	'@ *****************************************************************************************

	Public Function [Get](Byval s)
		Dim tmp, i, arrQs, t
		If Instr(s,":")>0 Then
			t = CRight(s,":") : s = CLeft(s,":")
		End If
		If isRewrite Then
			arrQs = Split(s_rwtU,"&")
			For i = 0 To Ubound(arrQs)
				If s = CLeft(arrQs(i),"=") Then
					tmp = RegReplace(s_url,s_rwtS,CRight(arrQs(i),"="))
					Exit For
				End If
			Next
		Else
			tmp = Request.QueryString(s)
		End If
		[Get] = Safe(tmp,t)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Post name[:type[separator]][:default]
	'@ 返  回:  如果有分隔符，则返回数组；如果没有分隔符，则返回经过处理的字符串。
	'@ 			返回值会根据不同的 type 参数值会进行不同的处理
	'@ 作  用:  安全化值
	'==Param====================================================================================
	'@ name String (字符串)
	'@   要获取的参数名，如省略其它参数则相当于原始的Request.Form
	'@ type(可选) String (字符串)
	'@   可以是以下字符串：
	'@    "s"  - 表示name是字符串类型的值，会自动处理其中的单引号(')为双单引号('')
	'@    "n"  - 表示name是数值型的值，会验证是否为数值
	'@    "d"  - 表示name是日期型的值，会验证是否为日期
	'@    "na" - 表示name是数值型的值，如果name验证不是数字，则会弹出alert警告框并返回前页
	'@    "da" - 表示name是日期型的值，如果name验证不是日期，则会弹出alert警告框并返回前页
	'@    "ne" - 表示name是数值型的值，如果name验证不是数字，则抛出用户错误信息
	'@    "de" - 表示name是日期型的值，如果name验证不是日期，则抛出用户错误信息
	'@ separator(可选) String (字符串)
	'@   name是由此字符串(特殊符号)隔开的序列，如不省略则会逐个检查name串中的值，并返回一个数组
	'@ default(可选) String (字符串)
	'@   如果name为空或按type检查不符合数值/日期要求，则赋给此默认值；序列则逐个赋值
	'@
	'@ 调用此方法可以返回一个经过处理的安全的Request.Form值，
	'@ 可以用于拼接SQL字符串而不会产生注入问题。
	'@ 如果你想到得到未经处理的原始值，不带任何参数就可以了。
	'==DEMO=====================================================================================
	'@ 传统: Request.Form("username")
	'@ 我们可以: AB.C.Post("username")
	'@ '假设有文本框name的value是Icecream's，则：
	'@ AB.C.Post("name")    '返回 Icecream's
	'@ AB.C.Post("name:s")  '返回 Icecream''s
	'@ '假设有文本框birth的value是1983-9-23，则：
	'@ AB.C.Post("birth:d") '返回 1983-9-23
	'@ '假设有文本框usertype的value是空，则：
	'@ AB.C.Post("usertype:n:1")  '返回 1，因为该参数不存在，这里返回默认值1
	'@ '假设有复选框组fav，被选中的复选框的value分别是1,4,6,11
	'@ AB.C.Post("fav:n, ") '返回数组 Array(1,4,6,11)
	'@ *****************************************************************************************

	Function Post(ByVal s)
		Dim t,tmp : tmp = ""
		If Instr(s,":")>0 Then
			t = CRight(s,":") : s = CLeft(s,":")
		End If
		Dim FormType
		If Has(Request.ServerVariables("HTTP_CONTENT_TYPE")) Then
			FormType = Split(Request.ServerVariables("HTTP_CONTENT_TYPE"), ";")(0)
		Else
			FormType = "notupload"
		End If
		If LCase(FormType) = "multipart/form-data" Then
			If Lcase(TypeName(upload)) = "cls_ab_upload" Then
				If upload.Form.Count>0 Then tmp = upload.Form(s)
			End If
		Else
			tmp = Request.Form(s)
		End If
		Post = Safe(tmp,t)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.CheckForm string, rule, require, emptyErrMsg|[emptyErrMsg:]ruleErrMsg
	'@ 返  回:  如果有分隔符，则返回数组；如果没有分隔符，则返回经过处理的字符串。
	'@ 			返回值会根据不同的 type 参数值会进行不同的处理
	'@ 作  用:  服务器端简单表单验证
	'==DESC=====================================================================================
	'@ string String (字符串)
	'@   待验证的字符串
	'@ rule "" (空字符串) 或 String (字符串)
	'@   验证规则，可以是正则表达式，也可以是以下字符串(如果仅验证字符串是否为空，则此参数可留空)：
	'@    "date" - 验证是否为合法的日期格式
	'@    "idcard" - 验证是否为合法的身份证号码
	'@    "english" - 验证是否只包含英文字母
	'@    "chinese" - 验证是否只包含中文字符
	'@    "username" - 验证是否是合法的用户名（4-20位，只能是大小写字母数字及下划线且以字母开头）
	'@    "email" - 验证是否是合法的E-mail地址
	'@    "int" - 验证是否为整数
	'@    "number" - 验证是否为数字
	'@    "double" - 验证是否为双精度数字
	'@    "price" - 验证是否为价格格式
	'@    "zip" - 验证是否为合法的邮编
	'@    "qq" - 验证是否为合法的QQ号
	'@    "phone" - 验证是否为合法的电话号码
	'@    "mobile" - 验证是否为合法的手机号码
	'@    "url" - 验证是否为合法的URL地址
	'@    "ip" - 验证是否为合法的IP地址
	'@   如果要同时验证多个规则，可以用“||”符号隔开。
	'@ require Integer (整数)
	'@   是否可以为空，0为可以为空，1为不能为空
	'@ emptyErrMsg String (字符串)
	'@   设置不能为空但验证结果为空的提示消息，如果消息中包含冒号(:)则需要先加"\"进行转义。
	'@   当存在ruleErrMsg参数时，此参数可以省略。
	'@ ruleErrMsg String (字符串)
	'@   验证后字符串不合规则的提示消息
	'==DEMO=====================================================================================
	'@ Dim UserName, UserPass, UserIdCard, UserEmail
	'@ UserName = AB.C.CheckForm(AB.C.Post("uname:s"),"username",1,"会员名不能为空！:不是有效的会员名！")
	'@ UserPass = AB.C.CheckForm(AB.C.Post("upass:s"),"",1,"密码不能为空！")
	'@ UserIdCard = AB.C.CheckForm(AB.C.Post("uidcard:s"),"idcard",0,"请输入正确的身份证号码！")
	'@ UserEmail = AB.C.CheckForm(AB.C.Post("uemail:s"),"email",1,"邮箱不能为空！:邮箱地址无效！")
	'@ *****************************************************************************************

	Function CheckForm(ByVal s, ByVal Rule, ByVal Require, ByVal ErrMsg)
		Dim tmpMsg, Msg, i
		tmpMsg = Replace(ErrMsg,"\:",chr(0))
		Msg = IIF(Instr(tmpMsg,":")>0,Split(tmpMsg,":"),Array("有项目不能为空",tmpMsg))
		If Require = 1 And isNul(s) Then
			If Instr(tmpMsg,":")>0 Then
				Alert Replace(Msg(0),chr(0),":") : Exit Function
			Else
				Alert Replace(tmpMsg,chr(0),":") : Exit Function
			End If
		End If
		If Not (Require = 0 And isNul(s)) Then
			If Left(Rule,1)=":" Then
				Dim pass,arrRule
				pass = False
				arrRule = Split(Mid(Rule,2),"||")
				For i = 0 To Ubound(arrRule)
					If Test(s,arrRule(i)) Then pass = True : Exit For
				Next
				If Not pass Then Alert(Replace(Msg(1),chr(0),":")) : Exit Function
			Else
				If Not Test(s,Rule) Then Alert(Replace(Msg(1),chr(0),":")) : Exit Function
			End If
		End If
		CheckForm = s
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.CheckDataFrom()
	'@ 返  回:  如果是站内提交返回真(True)，否则返回假(False)
	'@ 作  用:  检查数据是否从站内被提交，并返回检查的结果。
	'==Desc====================================================================================
	'@ 无
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Function CheckDataFrom()
		Dim v1, v2
		CheckDataFrom = False
		v1 = Lcase(Cstr(ServerVar("HTTP_REFERER")))
		v2 = Lcase(Cstr(ServerVar("SERVER_NAME")))
		v1 = Mid(v1,Instr(v1,"://")+3,len(v2))
		If v1 = v2 Then
			CheckDataFrom = True
		End If
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.CheckDataFromA()
	'@ 返  回:  无参数,无返回值
	'@ 作  用:  此方法将检查数据是否从站内被提交，
	'@ 			不同于 AB.C.CheckDataFrom 方法的是
	'@ 			如果不是站内提交的数据则会弹出警告信息“禁止从站点外部提交数据！”并返回前一页。
	'==Desc====================================================================================
	'@ 无
	'==DEMO=====================================================================================
	'@ 无
	'@ *****************************************************************************************

	Sub CheckDataFromA()
		If Not CheckDataFrom Then Alert "禁止从站点外部提交数据！"
	End Sub

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.ToNumber number, decimal
	'@ 返  回:  经过处理的数值
	'@ 作  用:  把参数number中的值转换为指定小数位数的数值
	'==DESC=====================================================================================
	'@ number : Float (浮点数) 待处理的数值
	'@ decimal : Integer (整数) 保留的小数位数
	'==DEMO=====================================================================================
	'@ AB.C.toNumber(123.3144,2) 返回值: 123.31
	'@ *****************************************************************************************

	Public Function toNumber(ByVal n, ByVal d)
		toNumber = FormatNumber(n,d,-1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.ToPrice number
	'@ 返  回:  带有货币符号的数值
	'@ 作  用:  把参数number中的值转换为带有货币符号的数值，
	'@ 			何种货币符号取决于服务器语言区域相关选项的设置
	'==DESC=====================================================================================
	'@ number : Numeric (数值) 带有货币符号的数值
	'==DEMO=====================================================================================
	'@ AB.C.toPrice(123.3144) 返回值: ￥123.31
	'@ *****************************************************************************************

	Public Function toPrice(ByVal n)
		toPrice = FormatCurrency(n,2,-1,0,-1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.ToPercent number
	'@ 返  回:  经过处理的百分比数值
	'@ 作  用:  把参数number中的值转换为带有两位小数的百分比样式
	'==DESC=====================================================================================
	'@ number : Float (浮点数) 待处理的数值
	'==DEMO=====================================================================================
	'@ AB.C.toPercent(0.123144)  返回值: 12.31%
	'@ *****************************************************************************************

	Public Function toPercent(ByVal n)
		toPercent = FormatPercent(n,2,-1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetImg String
	'@ 返  回:  获取含有<img>标签的所有SRC属性并存为数组
	'@ 作  用:  把取得字符串中含有<img>标签的SRC属性存为数组
	'==DESC=====================================================================================
	'@ String : 需要处理的字符串
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.GetImg("abc<img src='http://www.baidu.com/search/img/logo.gif'>defg")(0)
	'@ 返回: http://www.baidu.com/search/img/logo.gif
	'@ *****************************************************************************************

	Public Function GetImg(ByVal s)
		GetImg = GetImg__(s,0)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetImgTag String
	'@ 返  回:  获取<img>标签数组
	'@ 作  用:  获取字符串中所有匹配<img>标签并存为数组
	'==DESC=====================================================================================
	'@ String : 需要处理的字符串
	'==DEMO=====================================================================================
	'@ AB.C.Print AB.C.GetImgTag("abc<img src='http://www.baidu.com/search/img/logo.gif'>defg")(0)
	'@ 返回: <img src='http://www.baidu.com/search/img/logo.gif'>
	'@ *****************************************************************************************

	Public Function GetImgTag(ByVal s)
		GetImgTag = GetImg__(s,1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.Fill String, Len, FillStr
	'@ 返  回:  当字符串不够长度则填充以至达到设定长度，若够的话返回原字符串
	'@ 作  用:  当String的字符长度不够Len值，则用设定的FillStr值填充使总长度达到Len值，FillStr为空则用空格填充
	'==DESC=====================================================================================
	'@ String : 原字符串
	'@ Len : 比较字符长度
	'@ FillStr : 填充字符，若为空则表示用空格(nbsp;)填充
	'==DEMO=====================================================================================
	'@ NONE
	'@ *****************************************************************************************

	Function Fill(ByVal s, ByVal l, ByVal f)
		Dim le,i,tmp
		le = len(s)
		If AB.C.isNul(f) Then f = "&nbsp;"
		If le < l Then
			For i = 1 To l-le
				tmp = tmp & f
			Next
		End If
		Fill = s & tmp
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetScriptTime startTimer
	'@ 返  回:  脚本执行的毫秒数
	'@ 作  用:  返回一个从指定时间开始到程序结束时止的用脚本执行时间，精确到毫秒
	'==DESC=====================================================================================
	'@ startTimer : Timer (时间戳函数) 脚本开始时间戳
	'==DEMO=====================================================================================
	'@ Dim start : start = Timer()
	'@ '在这里放置你要测算时间的代码块
	'@ AB.C.Print "脚本共用时"& AB.C.GetScriptTime(start) &"毫秒"
	'@ *****************************************************************************************

	Public Function GetScriptTime(t)
		If IsNull(t) Or t&"" = "" Or t&"" = "0" Then t = Abx_Timer
		'GetScriptTime = FormatNumber((Timer()-t)*1000,3)
		GetScriptTime = FormatNumber((Timer()-t)*1000, 2, -1)
	End Function

	'@ *****************************************************************************************
	'@ 过程名:  AB.C.GetTables 获取所有表名
	'@ 返  回:  Array
	'@ 作  用:  获取所有表名信息数组
	'==DESC=====================================================================================
	'@ 参数:	无
	'==DEMO=====================================================================================
	'@ AB.C.GetTables => Array("Table1","Table2","Table3")
	'@ *****************************************************************************************

	Public Function GetTables()
		On Error Resume Next
		Dim a : a = Array()
		AB.Use "db" : AB.Use "A"
		Dim objRs:Set objRs = AB.db.Conn.OpenSchema(20)
		objRs.filter="table_type='table'"
		Do Until objRs.EOF
			a = AB.A.Push(a, objRs("table_name")&"")
			objRs.movenext()
		Loop
		objRs.close()
		Set objRs = nothing
		GetTables = a
		On Error Goto 0
	End Function

	Public Function ReplaceUrl(ByVal p, ByVal s)
		Dim arrQs,tmp
		If isRewrite Then
			arrQs = Split(s_rwtU,"&")
			For i = 0 To Ubound(arrQs)
				If p = CLeft(arrQs(i),"=") Then
					tmp = CRight(arrQs(i),"=")
					Exit For
				End If
			Next
			If Left(tmp,1) = "$" Then
				ReplaceUrl = ReplacePart(s_url, s_rwtS, tmp, s)
			End If
		Else
			ReplaceUrl = GetUrlWith("-" & p, p & "=" & s)
		End If
	End Function

	' ============== 以下辅助函数 ===================

		Private Function replacePart(ByVal txt, ByVal rule, ByVal part, ByVal replacement)
			If Not Test(txt, rule) Then
				replacePart = "[not match]"
				Exit Function
			End If
			Dim Match,i,j,ma,pos,uleft,ul
			i = Int(Mid(part,2))-1
			Set Match = RegMatch(txt,rule)(0)
			For j = 0 To Match.SubMatches.Count-1
				ma = Match.SubMatches(j)
				pos = Instr(txt,ma)
				If pos > 0 Then
					ul = Left(txt,pos-1)
					txt = Mid(txt,Len(ul)+1)
					If i = j Then
						replacePart = uleft & ul & Replace(txt,ma,replacement,pos-len(ul),1,0)
						Exit For
					End If
					uleft = uleft & ul & ma
					txt = Mid(txt, Len(ma)+1)
				End If
			Next
			Set Match = Nothing
		End Function

		Private Function FormatString(ByVal s, ByRef v, ByVal t)
			Dim i,n,k
			s = Replace(s,"\\",Chr(0))
			s = Replace(s,"\{",Chr(1))
			Select Case VarType(v)
				Case 8192,8194,8204,8209
					For i = 0 To Ubound(v)
						s = FormatReplace(s,i+t,v(i))
					Next
				Case 9
					Select Case TypeName(v)
						Case "Recordset"
							For i = 0 To v.Fields.Count - 1
								s = FormatReplace(s,i+t,v(i))
								s = FormatReplace(s,v.Fields.Item(i+t).Name,v(i))
							Next
						Case "Dictionary"
							For Each k In v
								s = FormatReplace(s,k,v(k))
							Next
						Case "Cls_AB_List"
							For i = 0 To v.End
								s = FormatReplace(s,i+t,v(i))
								s = FormatReplace(s,v.IndexHash(i),v(i))
							Next
						Case "ISubMatches", "SubMatches"
							For i = 0 To v.Count - 1
								s = FormatReplace(s,i+t,v(i))
							Next
					End Select
				Case 8
					Select Case TypeName(v)
						Case "IMatch2", "Match"
							s = FormatReplace(s,t,v.Value)
							For i = 0 To v.SubMatches.Count - 1
								s = FormatReplace(s,i+t+1,v.SubMatches(i))
							Next
						Case Else
							s = FormatReplace(s,t,v)
					End Select
				Case Else
					s = FormatReplace(s,t,v)
			End Select
			s = Replace(s,Chr(1),"{")
			FormatString = Replace(s,Chr(0),"\")
		End Function

		Private Function FormatReplace(ByVal s, ByVal t, ByVal v)
			Dim tmp,rule,ru,kind,matches,match
			v = IfHas(v,"")
			rule = "\{" & t & "(:((N[,\(%]?(\d+)?)|(D[^\}]+)|(E[^\}]+)|U|L))\}"
			If Test(s,rule) Then
				Set matches = RegMatch(s,rule)
				For Each match In matches
					kind = RegReplace(match.Value, rule, "$2")
					ru = "{"&t&":"&kind&"}"
					Select Case Left(kind,1)
						Case "N"
							If isNumeric(v) Then
								Dim style,group,parens,percent,deci
								style = RegReplace(kind,"N([,\(%])?(\d+)?","$1")
								If style = "," Then group = -1
								If style = "(" Then parens = -1
								If style = "%" Then percent = -1
								deci = RegReplace(kind,"N([,\(%])?(\d+)?","$2")
								If isNul(style) And isNul(deci) Then
									s = Replace(s, ru, IIF(Instr(Cstr(v),".")>0 And v<1,"0" & v,v),1,-1,1)
								Else
									deci = IfHas(deci,-1)
									If percent Then
										s = Replace(s, ru, FormatNumber(v*100,deci,-1) & "%",1,-1,1)
									Else
										s = Replace(s, ru, FormatNumber(v,deci,-1,parens,group),1,-1,1)
									End If
								End If
							End If
						Case "D"
							If isDate(v) Then
								s = Replace(s, ru, DateTime(v,Mid(kind,2)),1,-1,1)
							End If
						Case "U"
							s = Replace(s, ru, UCase(v),1,-1,1)
						Case "L"
							s = Replace(s, ru, LCase(v),1,-1,1)
						Case "E"
							tmp = Replace(Mid(kind,2),"%s", "v")
							tmp = Eval(tmp)
							s = Replace(s, ru, tmp,1,-1,1)
					End Select
				Next
			Else
				s = Replace(s,"{" & t & "}",v,1,-1,1)
			End If
			FormatReplace = s
		End Function

		Private Function isIDCard(ByVal s)
			Dim Ai, BirthDay, arrVerifyCode, Wi, i, AiPlusWi, modValue, strVerifyCode
			isIDCard = False
			If Len(s) <> 15 And Len(s) <> 18 Then Exit Function
			Ai = IIF(Len(s) = 18,Mid(s, 1, 17),Left(s, 6) & "19" & Mid(s, 7, 9))
			If Not IsNumeric(Ai) Then Exit Function
			If Not Test(Left(Ai,6),"^(1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-5]|8[12]|91)\d{2}[01238]\d{1}$") Then Exit Function
			BirthDay = Mid(Ai, 7, 4) & "-" & Mid(Ai, 11, 2) & "-" & Mid(Ai, 13, 2)
			If IsDate(BirthDay) Then
				If cDate(BirthDay) > Date() Or cDate(BirthDay) < cDate("1870-1-1") Then  Exit Function
			Else
				Exit Function
			End If
			arrVerifyCode = Split("1,0,x,9,8,7,6,5,4,3,2", ",")
			Wi = Split("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2", ",")
			For i = 0 To 16
				AiPlusWi = AiPlusWi + CInt(Mid(Ai, i + 1, 1)) * Wi(i)
			Next
			modValue = AiPlusWi Mod 11
			strVerifyCode = arrVerifyCode(modValue)
			Ai = Ai & strVerifyCode
			If Len(s) = 18 And LCase(s) <> Ai Then Exit Function
			isIDCard = True
		End Function

		Private Function GetImg__(ByVal s, ByVal t)
			Dim a(), img, Matches, m, i : i = 0
			ReDim a(-1)
			img = "<img([^>]+?)(/?)>"
			If Has(s) And Test(s, img) Then
				s = Replace(s, vbCrLf, " ")
				s = Replace(s, vbTab, " ")
				Set Matches = AB.C.RegMatch(s, "(<img\s[^>]*src\s*=\s*([""|']?))([^""'>]+)(\2[^>]*>)")
				For Each m In Matches
					ReDim Preserve a(i)
					a(i) = IIF(t=0,m.SubMatches(2),m.value)
					i = i + 1
				Next
			End If
			GetImg__ = a
		End Function

		Private Function Abx_Param(ByVal s)
			Dim arr(1),t : t = Instr(s,":")
			If t > 0 Then
				arr(0) = Left(s,t-1) : arr(1) = Mid(s,t+1)
			Else
				arr(0) = s : arr(1) = ""
			End If
			Abx_Param = arr
		End Function

End Class
%>